Recently while reading blog on universal reference by scott meyers i came along statement that "if you can take the address of an expression, the expression is an lvalue." but is this really true
Suppose i have following code
class Test
{
};
int main()
{
std::cout << "Address is " << &(Test()) << std::endl;
Test() = Test();
Test&& t = Test();
return 0;
}
In above case Test() is temporary i.e rvalue and i am able to take address of that (with gcc we can use -fpremissive and with msvc it will compile directly) so with this we can say it is lvalue and also bcoz we can do Test() = Test() but since we can take rvalue reference to it so it should be rvalue.
So why we always say that if we can take address of variable then it is lvalue ?
Your first code is incorrect because the declaration of z
should be int*
, this code compiles and works fine:
int x = 12; // x is lvalue
int& y = x; // y is lvalue reference
int *z = &y; // can take address of lvalue reference (address of the referenced)
assert(z == &x);
For your second example, Test()
is actually a prvalue
and you cannot take its address in a portable way as mentioned per the standard.
MSVC has extensions that allow you to take the address of prvalue
s, and GCC allows you to enable this kind of extension using -fpermissive
:
Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive will allow some nonconforming code to compile.
This means that Scott Meyers is right and the compilers are wrong, at least in the question of conforming to the standard. Also, by passing -fpermissive
you told gcc to be less strict, i.e. allow your non-conforming code to compile. To be completely conforming, you should always compile with -pedantic
or -pedantic-errors
(because just like MSVC, gcc also enables some language extensions by default).