Title
Lvalue-to-rvalue conversions in expression statements
Status
c++11
Section
8.3 [stmt.expr]
Submitter
Hans Boehm

Created on 2010-03-16.00:00:00 last changed 96 months ago

Messages

Date: 2011-03-15.00:00:00

[Voted into the WP at the March, 2011 meeting.]

Date: 2011-01-15.00:00:00

Proposed resolution (January, 2011):

  1. Add a new paragraph after Clause 7 [expr] paragraph 10:

  2. In some contexts, an expression only appears for its side-effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded. The array-to-pointer (7.3.3 [conv.array]) and function-to-pointer (7.3.4 [conv.func]) standard conversions are not applied. The lvalue-to-rvalue conversion (7.3.2 [conv.lval]) is applied only if the expression is an lvalue of volatile-qualified type and it has one of the following forms:

    • id-expression (_N4567_.5.1.1 [expr.prim.general]),

    • subscripting (7.6.1.2 [expr.sub]),

    • class member access (7.6.1.5 [expr.ref]),

    • indirection (7.6.2.2 [expr.unary.op]),

    • pointer-to-member operation (7.6.4 [expr.mptr.oper]),

    • conditional expression (7.6.16 [expr.cond]) where both the second and the third operand are one of the above, or

    • comma expression (7.6.20 [expr.comma]) where the right operand is one of the above.

  3. Change 7.6.1.9 [expr.static.cast] paragraph 6 as follows:

  4. Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-value expression (Clause Clause 7 [expr]). The expression value is discarded. [Note: however, if the value is in a temporary object (6.7.7 [class.temporary]), the destructor for that object is not executed until the usual time, and the value of the object is preserved for the purpose of executing the destructor. —end note] The lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), and function-to-pointer (7.3.4 [conv.func]) standard conversions are not applied to the expression.
  5. Change 7.6.20 [expr.comma] paragraph 1 as follows:

  6. ...A pair of expressions separated by a comma is evaluated left-to-right; and the value of the left expression is discarded a discarded-value expression (Clause Clause 7 [expr]).83 The lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), and function-to-pointer (7.3.4 [conv.func]) standard conversions are not applied to the left expression. Every value computation...
  7. Change 8.3 [stmt.expr] paragraph 1 as follows:

  8. ...The expression is evaluated and its value is discarded a discarded-value expression (clause Clause 7 [expr]). The lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), and function-to-pointer (7.3.4 [conv.func]) standard conversions are not applied to the expression. All side effects...
Date: 2010-03-16.00:00:00

C and C++ differ in the treatment of an expression statement, in particular with regard to whether a volatile lvalue is fetched. For example,

    volatile int x;
    void f() {
        x;    // Fetches x in C, not in C++
    }

The reason C++ is different in this regard is principally due to the fact that an assignment expression is an lvalue in C++ but not in C. If the lvalue-to-rvalue conversion were applied to expression statements, a statement like

    x = 5;

would write to x and then immediately read it.

It is not clear that the current approach to dealing with the difference in assignment expressions is the only or best approach; it might be possible to avoid the unwanted fetch on the result of an assignment statement without giving up the fetch for a variable appearing by itself in an expression statement.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetmessages: + msg3321
2011-04-10 00:00:00adminsetstatus: tentatively ready -> fdis
2011-02-28 00:00:00adminsetstatus: review -> tentatively ready
2010-11-29 00:00:00adminsetmessages: + msg3081
2010-11-29 00:00:00adminsetstatus: open -> review
2010-03-16 00:00:00admincreate