<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 1054</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="1054"></A><H4>1054.
  
Lvalue-to-rvalue conversions in expression statements
</H4>
<B>Section: </B>8.3&#160; [<A href="https://wg21.link/stmt.expr">stmt.expr</A>]
 &#160;&#160;&#160;

 <B>Status: </B>C++11
 &#160;&#160;&#160;

 <B>Submitter: </B>Hans Boehm
 &#160;&#160;&#160;

 <B>Date: </B>2010-03-16<BR>


<P>[Voted into the WP at the March, 2011 meeting.]</P>

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

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

<P>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</P>

<PRE>
    x = 5;
</PRE>

<P>would write to x and then immediately read it.</P>

<P>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.</P>

<P><B>Proposed resolution (January, 2011):</B></P>

<OL>
<LI><P>Add a new paragraph after Clause 7 [<A href="https://wg21.link/expr">expr</A>] paragraph
10:</P></LI>

<BLOCKQUOTE>

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

<UL>
<LI><P><INS><I>id-expression</I> (_N4567_.5.1.1 [<A href="https://wg21.link/expr.prim.general">expr.prim.general</A>]),</INS></P></LI>

<LI><P><INS>subscripting (7.6.1.2 [<A href="https://wg21.link/expr.sub">expr.sub</A>]),</INS></P></LI>

<LI><P><INS>class member access (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]),</INS></P></LI>

<LI><P><INS>indirection (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]),</INS></P></LI>

<LI><P><INS>pointer-to-member operation (7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>]),</INS></P></LI>

<LI><P><INS>conditional expression (7.6.16 [<A href="https://wg21.link/expr.cond">expr.cond</A>]) where both
the second and the third operand are one of the above, or</INS></P></LI>

<LI><P><INS>comma expression (7.6.20 [<A href="https://wg21.link/expr.comma">expr.comma</A>]) where the right
operand is one of the above.</INS></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#6">expr.static.cast</A>] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

Any expression can be explicitly converted to type <I>cv</I>
<TT>void</TT><INS>, in which case it becomes a discarded-value
expression (Clause 7 [<A href="https://wg21.link/expr">expr</A>])</INS>.  <DEL>The expression
value is discarded.</DEL> [<I>Note:</I> however, if the value is in a
temporary object (6.8.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]), 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.
&#8212;<I>end note</I>] <DEL>The lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer (7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and
function-to-pointer (7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions
are not applied to the expression.</DEL>

</BLOCKQUOTE>

<LI><P>Change 7.6.20 [<A href="https://wg21.link/expr.comma#1">expr.comma</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...A pair of expressions separated by a comma is evaluated
left-to-right<INS>;</INS> <DEL>and the value of</DEL> the left
expression is <DEL>discarded</DEL> <INS>a discarded-value expression
(Clause 7 [<A href="https://wg21.link/expr">expr</A>])</INS>.<SUP>83</SUP> <DEL>The
lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer (7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are not applied to the left
expression.</DEL> Every value computation...

</BLOCKQUOTE>

<LI><P>Change 8.3 [<A href="https://wg21.link/stmt.expr#1">stmt.expr</A>] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...The expression is <DEL>evaluated and its value is discarded</DEL>
<INS>a discarded-value expression (Clause 7 [<A href="https://wg21.link/expr">expr</A>])</INS>. <DEL>The lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),
array-to-pointer (7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are not applied to the
expression.</DEL>  All side effects...

</BLOCKQUOTE>

</OL>

<BR><BR>
</BODY>
</HTML>
