I'm using N3936 as a reference here (please correct this question if any of the C++14 text differs).
Under 3.10 Lvalues and rvalues we have:
Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.
However the definition of lvalue reads:
An lvalue [...] designates a function or an object.
In 4.1 Lvalue-to-rvalue conversion the text appears:
[...] In all other cases, the result of the conversion is determined according to the following rules: [...] Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.
My question is: what happens in code where the lvalue does not designate an object? There are two canonical examples:
Example 1:
int *p = nullptr;
*p;
int &q = *p;
int a = *p;
Example 2:
int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);
Which lines (if any) are ill-formed and/or cause undefined behaviour?
Referring to Example 1: is *p
an lvalue? According to my first quote it must be. However, my second quote excludes it since *p
does not designate an object. (It's certainly not an xvalue or a prvalue either).
But if you interpret my second quote to mean that *p
is actually an lvalue, then it is not covered at all by the lvalue-to-rvalue conversion rules. You may take the catch-all rule that "anything not defined by the Standard is undefined behaviour" but then you must permit null references to exist, so long as there is no lvalue-to-rvalue conversion performed.
History: This issue was raised in DR 232 . In C++11 the resolution from DR232 did in fact appear. Quoting from N3337 Lvalue-to-rvalue conversion:
If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
which still appears to permit null references to exist - it only clears up the issue of performing lvalue-to-rvalue conversion on one. Also discussed on this SO thread
The resolution from DR232 no longer appears in N3797 or N3936 though.