3
votes

§ 6.3.2.1:2 of ISO/IEC 9899:2011, i.e. the “ISO C11 standard”, says:

2 Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion. If the lvalue has qualified type, the value has the unqualified version of the type of the lvalue; additionally, if the lvalue has atomic type, the value has the non-atomic version of the type of the lvalue; otherwise, the value has the type of the lvalue. If the lvalue has an incomplete type and does not have array type, the behavior is undefined. If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

But isn't a dereferenced pointer also an lvalue, just like the pointer itself? E.g. int *ptr; ptr = malloc(…); *ptr = 1

So why is the * operator not mentioned – or do I confuse something here?

1
What is it you think should be in that paragraph? In *ptr, ptr is an lvalue. Then is is, per 6.3.2.1 2, converted to its value. Then * operates on it, producing an lvalue for the-pointed to object. Then *ptr is the left operand of an assignment operator, so it remains an lvalue. Then the assignment assigns 1 to the pointed-to object.Eric Postpischil
The paragraph you quote is about how lvalues behave , not about how lvalues are created (the latter is where the * in *ptr would be discussedM.M

1 Answers

4
votes

You're missing section 6.5.3.2p4, which discusses the semantics of indirection operator *:

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type "pointer to type", the result has type "type". If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

The operator itself is defined to produce an lvalue.