TL;DR
Given the following code:
int* ptr;
*ptr = 0;
does *ptr
require an lvalue-to-rvalue conversion of ptr
before applying indirection?
The standard covers the topic of lvalue-to-rvalue in many places but does not seem to specify enough information to determine whether the * operator require such a conversion.
Details
The lvalue-to-rvalue conversion is covered in N3485 in section 4.1
Lvalue-to-rvalue conversion paragraph 1 and says (emphasis mine going forward):
A glvalue (3.10) of a non-function, non-array type T can be converted
to a prvalue.53 If T is an incomplete type, a program that
necessitates this conversion is ill-formed. 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.[...]
So does *ptr = 0;
necessitate this conversion?
If we go to section 4
paragraph 1 it says:
[...]A standard conversion sequence will be applied to an expression
if necessary to convert it to a required destination type.
So when is it necessary? If we look at section 5
Expressions the lvalue-to-rvalue conversion is mentioned in paragraph 9 which says:
Whenever a glvalue expression appears as an operand of an operator
that expects a prvalue for that operand, the lvalue-to-rvalue (4.1),
array-to-pointer (4.2), or function-to-pointer (4.3) standard
conversions are applied to convert the expression to a prvalue. [...]
and paragraph 11 which says:
In some contexts, an expression only appears for its side effects.
Such an expression is called a discarded-value expression.[...] The
lvalue-to-rvalue conversion (4.1) is applied if and only if the
expression is an lvalue of volatile-qualified type and it is one of
the following [...]
neither paragraph seems to apply to this code sample and 5.3.1
Unary operators paragraph 1 it says:
The unary * operator performs indirection: the expression to which it
is applied shall be a pointer to an object type, or a pointer to a
function type and the result is an lvalue referring to the object or
function to which the expression points. If the type of the expression
is “pointer to T,” the type of the result is “T.” [ Note: indirection
through a pointer to an incomplete type (other than cv void) is valid.
The lvalue thus obtained can be used in limited ways (to initialize a
reference, for example); this lvalue must not be converted to a
prvalue, see 4.1. —end note ]
it does not seem to require the value of the pointer and I don't see any requirements for a conversion of the pointer here am I missing something?
Why do we care?
I have seen an answer and comments in other questions that claim the use of an uninitialized pointer is undefined behavior due the need for an lvalue-to-rvalue conversion of ptr
before applying indirection. For example: Where exactly does C++ standard say dereferencing an uninitialized pointer is undefined behavior? makes this argument and I can not reconcile the argument with what is laid out in any of the recent draft versions of the standard. Since I have seen this several times I wanted to get clarification.
The actual proof of undefined behavior is not as important since as I noted in the linked question above we have others way to get to undefined behavior.
See Question&Answers more detail:
os