Commenting in the FAQ is often misleading; both AE::c6 and AE::c7 are lvalues. If the definition of AE::c7 missing, this code violates one rule of definition:
An expression is potentially evaluated if it is not an unvalued operand or its subexpression. A variable whose name is displayed as a potentially evaluated expression is odr-used if it is not an object that meets the requirements for displaying in a constant expression and lvalue-to-rvalue conversion is immediately applied. [...]
[...]
Each program must contain exactly one definition of each non-built-in function or variable, which is used as an odr program; no diagnostics required.
In practice, the linker usually generates an error if the compiler really needed an object address. In your case, if p2 not used later, then the compiler will not need an address, since optimization will remove the definition of p1 . An even more common case when this happens is things like the following:
std::vector<int> v; v.push_back( AE::c6 );
Since std::vector<>::push_back takes a link, there is no immediate conversion to lvalue-to-rvalue, but a definition is required. In practice, std::vector<>::push_back is a template (usually built-in), so the compiler can see its implementation and extend the value down to the function to the place where the lvalue-to-rvalue conversion actually takes place and the code will compile and work. But it is still formally undefined.
James kanze
source share