The comment in the FAQ is very misleading; both AE::c6
and
AE::c7
are lvalues. If there is no definition of AE::c7
,
the code in question violates the one definition rule:
An expression is potentially evaluated unless it is an
unevaluated operand or a subexpression thereof. A variable
whose name appears as a potentially-evaluated expression is
odr-used unless it is an object that satisfies the requirements
for appearing in a constant expression and the lvalue-to-rvalue
conversion is immediately applied. [...]
[...]
Every program shall contain exactly one definition of every
non-inline function or variable that is odr-used in that
program; no diagnostic required.
In practice, the linker will generally generate an error if
the compiler actually needed the address of the object. In your
case, if p2
isn't used later, then the compiler won't need the
address, since optimization will remove the definition of p1
.
An even more frequent case where this occurs are things like the
following:
std::vector<int> v;
v.push_back( AE::c6 );
Since std::vector<>::push_back
takes a reference, there is no
immediate lvalue-to-rvalue conversion, and a definition is
required. In practice, std::vector<>::push_back
is a template
function (usually inline), so the compiler can see into its
implementation, and propagate the value down into the function
to the place where the lvalue-to-rvalue conversion actually
occurs, and the code will compile and work. But it is still
formally undefined behavior.