Re: warning C4238 : cast reference in void*




Eric wrote:
Alex Blekhman wrote:
Eric wrote:
CString foo2(CString aString)
{
return aString;
}
void* foo(CString &aString)
{
return (void*)&foo2(aString); //give C4238 warning
}
int main()
{
CString aString;
void* ptr = foo(aString);
}

foo2 returns temporary _copy_ of CString. So, you're trying
to return an address of temporary object. This code will
crash at runtime.

Sorry all, I understand that local variable are temporary objet. My
question was more about the warning C4238 and the class rvalue, lvalue
issue.

why void* ptr = &foo2(aString) give this warning ?

because ptr is now a pointer to a function. This is unrelated to the
previous issue.

Do you understand what rvalue and lvalue mean?
An lvalue is a variable that can be placed on the *left* of the
assignment operator.
That means that an lvalue is mutable or non-constant or assigneable.
An rvalue, on the other hand, is a constant.

example:
int n(5);
n = 99; // ok
// n is an lvalue. You can continue to modify it.

const int m(5);
// m = 99; // not allowed
// m is an rvalue. You can't modify it.
// It can only appear on the right side of the assignment operator
following its initialisation.

Now go back to the original problem and you'll recognize that what the
compiler is saying is
"i can use a proprietary extension, which contradicts what is "defined"
in this language, to do what you want only *if* you provide a constant
rvalue"
Which basicly means that if you try this with a different compiler, it
will probably fail.

IMHO, the above is pure bull***, because the only way that the
compiler would be able to safely support this is by declaring and
initializing:
const void* const ptr = whatever();
and since casting strips both the type and the constantness of the
pointer, you end up fried anyways.
Also, for the sake of completeness, a const_cast can convert the rvalue
to an lvalue as well.
So much for that extension.

.