Passing a char pointer to a function accepting a reference to a char array
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
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
?
c++
add a comment |Â
up vote
7
down vote
favorite
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
?
c++
How sure are you thatvalue
points to the start of achar[SIZE]
? You might be able toreinterpret_cast
but I'm not certain. I wouldn't recommend in any case.
â François Andrieux
3 hours ago
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 doesDoSomething
always need an array of lengthSIZE
? Why can'tBeforeDoingSomething
always use an array of lengthSIZE
instead of a pointer and length?
â alter igel
3 hours ago
The reason for this awkward situation is because this is happening within a DLL. The developer who wroteDoSomething
wrote it this way, and when a call is made into my DLL it's in the form inside ofBeforeDoingSomething
. I'm not sure how to even go about enforcing something likechar(&value)[SIZE]
when it comes to people calling into the DLL (which the callers will not be C++)
â Zulukas
3 hours ago
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
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
?
c++
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
?
c++
c++
edited 5 mins ago
user2357112
142k12146224
142k12146224
asked 3 hours ago
Zulukas
305412
305412
How sure are you thatvalue
points to the start of achar[SIZE]
? You might be able toreinterpret_cast
but I'm not certain. I wouldn't recommend in any case.
â François Andrieux
3 hours ago
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 doesDoSomething
always need an array of lengthSIZE
? Why can'tBeforeDoingSomething
always use an array of lengthSIZE
instead of a pointer and length?
â alter igel
3 hours ago
The reason for this awkward situation is because this is happening within a DLL. The developer who wroteDoSomething
wrote it this way, and when a call is made into my DLL it's in the form inside ofBeforeDoingSomething
. I'm not sure how to even go about enforcing something likechar(&value)[SIZE]
when it comes to people calling into the DLL (which the callers will not be C++)
â Zulukas
3 hours ago
add a comment |Â
How sure are you thatvalue
points to the start of achar[SIZE]
? You might be able toreinterpret_cast
but I'm not certain. I wouldn't recommend in any case.
â François Andrieux
3 hours ago
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 doesDoSomething
always need an array of lengthSIZE
? Why can'tBeforeDoingSomething
always use an array of lengthSIZE
instead of a pointer and length?
â alter igel
3 hours ago
The reason for this awkward situation is because this is happening within a DLL. The developer who wroteDoSomething
wrote it this way, and when a call is made into my DLL it's in the form inside ofBeforeDoingSomething
. I'm not sure how to even go about enforcing something likechar(&value)[SIZE]
when it comes to people calling into the DLL (which the callers will not be C++)
â Zulukas
3 hours ago
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.â François Andrieux
3 hours ago
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.â François Andrieux
3 hours ago
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?â alter igel
3 hours ago
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?â alter igel
3 hours ago
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++)â Zulukas
3 hours ago
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++)â Zulukas
3 hours ago
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
6
down vote
accepted
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)));
Isstd::launder
here because of the strict aliasing rule?
â Quimby
3 hours ago
1
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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 (asreinterpret_cast
doesn't do that for you, as the pointers are not interconvertible).
â geza
3 hours ago
 |Â
show 7 more comments
up vote
2
down vote
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.
add a comment |Â
up vote
2
down vote
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.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
accepted
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)));
Isstd::launder
here because of the strict aliasing rule?
â Quimby
3 hours ago
1
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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 (asreinterpret_cast
doesn't do that for you, as the pointers are not interconvertible).
â geza
3 hours ago
 |Â
show 7 more comments
up vote
6
down vote
accepted
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)));
Isstd::launder
here because of the strict aliasing rule?
â Quimby
3 hours ago
1
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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 (asreinterpret_cast
doesn't do that for you, as the pointers are not interconvertible).
â geza
3 hours ago
 |Â
show 7 more comments
up vote
6
down vote
accepted
up vote
6
down vote
accepted
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)));
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)));
edited 3 hours ago
answered 3 hours ago
user2079303
69.6k550109
69.6k550109
Isstd::launder
here because of the strict aliasing rule?
â Quimby
3 hours ago
1
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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 (asreinterpret_cast
doesn't do that for you, as the pointers are not interconvertible).
â geza
3 hours ago
 |Â
show 7 more comments
Isstd::launder
here because of the strict aliasing rule?
â Quimby
3 hours ago
1
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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 (asreinterpret_cast
doesn't do that for you, as the pointers are not interconvertible).
â geza
3 hours ago
Is
std::launder
here because of the strict aliasing rule?â Quimby
3 hours ago
Is
std::launder
here because of the strict aliasing rule?â Quimby
3 hours ago
1
1
@Quimby Exactly.
â user2079303
3 hours ago
@Quimby Exactly.
â user2079303
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
I think that launder is mandatory here, it is needed in the case of char array as well.
â geza
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@user2079303 Thank you.
â Quimby
3 hours ago
@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
3 hours ago
@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
3 hours ago
 |Â
show 7 more comments
up vote
2
down vote
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.
add a comment |Â
up vote
2
down vote
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.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
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.
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.
answered 3 hours ago
geza
10.2k22465
10.2k22465
add a comment |Â
add a comment |Â
up vote
2
down vote
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.
add a comment |Â
up vote
2
down vote
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.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
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.
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.
edited 3 hours ago
answered 3 hours ago
crayzeewulf
4,03011927
4,03011927
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52560364%2fpassing-a-char-pointer-to-a-function-accepting-a-reference-to-a-char-array%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
How sure are you that
value
points to the start of achar[SIZE]
? You might be able toreinterpret_cast
but I'm not certain. I wouldn't recommend in any case.â François Andrieux
3 hours ago
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 lengthSIZE
? Why can'tBeforeDoingSomething
always use an array of lengthSIZE
instead of a pointer and length?â alter igel
3 hours ago
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 ofBeforeDoingSomething
. I'm not sure how to even go about enforcing something likechar(&value)[SIZE]
when it comes to people calling into the DLL (which the callers will not be C++)â Zulukas
3 hours ago