10

I'm trying to call this method

#define SIZE 16
void DoSomething(char(&value)[SIZE])
{
}

From this method:

void BeforeDoingSomething(char* value, int len)
{
    if (len == SIZE)
    {
        DoSomething(value);
    }
}

Attempting to do this gives me this error:

a reference of type "char (&)[16]" (not const-qualified) cannot be initialized with a value of type "char *"

Any tips for how to get the compiler to accept value passed in the function BeforeDoingSomething?

3
  • How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case. Commented Sep 28, 2018 at 17:45
  • I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length? Commented Sep 28, 2018 at 17:51
  • The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++) Commented Sep 28, 2018 at 18:04

3 Answers 3

6

As the error explains, you cannot initialize a reference to an array using a pointer.

If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:

DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));
Sign up to request clarification or add additional context in comments.

10 Comments

Is std::launder here because of the strict aliasing rule?
@Quimby Exactly.
I think that launder is mandatory here, it is needed in the case of char array as well.
@Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
@geza but why wouldn't it point to the array? I don't see any unions or const pointers there, so there isn't need for pointer redirection, right? So without the launder, the casted array pointer could decay into different location than the original pointer points to?
|
3

You can do it like this, but only in the case if there is a char[16] at the address where value points:

DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));

It is the same case as the first example here.

Comments

3

The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.

Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:

#include <iostream>
#include <vector>
#include <string>

constexpr int SIZE = 16 ;

void DoSomething(char (&value)[SIZE])
{
    std::cout << "Do it!" << std::endl ;
}

void BeforeDoingSomething(char* value, int len)
{
    if (len == SIZE)
    {
        char tmp_array[SIZE] ;
        std::copy(value, value + len, tmp_array) ;
        DoSomething(tmp_array);
    } else {
        std::cout << "Length: " << len << std::endl ;   
    }
}

int main()
{
    std::string foo (SIZE, '-') ;
    BeforeDoingSomething(foo.data(), foo.size()) ;

    std::vector<char> bar (SIZE) ;
    BeforeDoingSomething(bar.data(), bar.size()) ;

    std::string qux ;
    BeforeDoingSomething(qux.data(), qux.size()) ;

    return 0 ;   
}

Try it online here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.