This gcc 7.1 document When is the current VOLUME C ++ object available? I quote (my emphasis in the future):
The C ++ standard is different from the C standard when handling volatile objects. It cannot indicate what constitutes volatile access , except that C ++ should behave similarly to C with respect to volatile
The C and C ++ language specifications differ when accessing an object in the void context:
and provides this example:
volatile int *src = somevalue; *src;
and continues:
The C ++ standard states that such expressions do not undergo lvalue conversion to rvalue and that the type of the dereference object may be incomplete. The C ++ standard does not explicitly state that it is an lvalue for the rvalue transform, which is responsible for causing access.
which should keep in mind the draft standard section 5.3.1 Unary operators, paragraph 1, which states:
The unary operator * performs an indirect call: the expression to which it is applied must be a pointer to the type of the object or a pointer to the type of the function, and the result is an lvalue that refers to the object or functions to which the expression refers. [...]
and following the links:
When using the volatile reference, g ++ does not treat equivalent expressions as volatile references, but instead gives a warning that there is no volatile access. The rationale for this is that otherwise it becomes difficult to determine where volatile access occurs, and it is impossible to ignore the return value from functions that return volatile references. Again , if you want to force read, enter the rvalue link .
so it looks like this: gcc prefers to handle references to mutable in different ways and in order to make it read, which you need to pass to the r-value, for example:
static_cast<volatile int>( c ) ;
which generates a prvalue and therefore the conversion of lvalue to rvalue from section 5.2.9 Static cast:
The result of static_cast (v) is the result of converting v to type T. If T is a lvalue reference type or rvalue reference to a function type, the result is lvalue; if T is an rvalue reference to an object type, the result is an xvalue; Otherwise, the result will be prvalue.
Refresh
The C ++ 11 draft adds 5 expression 11, which states:
In some contexts, an expression appears only for its side effects. Such an expression is called a discarded value expression. The expression is evaluated and its value is discarded. Standard conversions using the pointer array (4.2) and the pointer function (4.3) do not apply. The lvalue-to-rvalue (4.1) transformation is applied if and only if the expression is an lvalue of a volatile-qualified type and is one of the following :
and includes:
- id expression (5.1.1),
This seems ambiguous to me, because with respect to a; and c; Section 5.1.1 p8 says that it is an lvalue , and it is not obvious to me that it covers this case, but since Jonathan found DR 1054 it says that it really covers this case.