Topic: lvalue


Author: sachs@fnal.gov ("David Sachs")
Date: Sat, 1 Mar 2003 06:14:21 +0000 (UTC)
Raw View
The C++ standard specifies that the result of a unary increment operator or
of an assignment operator is an lvalue.

However, the standard also appears to specify that using such a result as an
lvalue produces undefined behavior, because these operations do not create
sequence points.

"... Between the previous and next sequence point a scalar object shall have
its stored value modified at most once by the evaluation of an expression.
...; otherwise the behavior is undefined."   (Section 5 paragraph 4)

// Example
int i = 0;
++(++i);    // UNDEFINED


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jdennett@acm.org (James Dennett)
Date: Mon, 3 Mar 2003 03:38:24 +0000 (UTC)
Raw View
David Sachs wrote:
> The C++ standard specifies that the result of a unary increment operator or
> of an assignment operator is an lvalue.
>
> However, the standard also appears to specify that using such a result as an
> lvalue produces undefined behavior, because these operations do not create
> sequence points.
>
> "... Between the previous and next sequence point a scalar object shall have
> its stored value modified at most once by the evaluation of an expression.
> ...; otherwise the behavior is undefined."   (Section 5 paragraph 4)
>
> // Example
> int i = 0;
> ++(++i);    // UNDEFINED

That is, indeed, undefined.  But

int i(0);
int *p(&++i);

is not; it is an indefensible way of writing

int i(0);
++i;
int *p(&i);

It's also legal to write

void f(int &) {}

int main() {
   int i;
   f(++i);
}

which would not be the case if ++i were an rvalue, because
an rvalue cannot be bound to a non-const reference.

In conclusion: you can use ++i as an l-value, it's just that
writing to that l-value is undefined.

I think there is some lack of clarity on the standard where
it should say that using the value of ++i does not constitute
a violation of other rules, but that doesn't appear to affect
the issue addressed in your post.

-- James.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Mon, 3 Mar 2003 03:39:39 +0000 (UTC)
Raw View
On Sat, 1 Mar 2003 06:14:21 +0000 (UTC), sachs@fnal.gov ("David
Sachs") wrote in comp.std.c++:

> The C++ standard specifies that the result of a unary increment operator or
> of an assignment operator is an lvalue.
>
> However, the standard also appears to specify that using such a result as an
> lvalue produces undefined behavior, because these operations do not create
> sequence points.
>
> "... Between the previous and next sequence point a scalar object shall have
> its stored value modified at most once by the evaluation of an expression.
> ...; otherwise the behavior is undefined."   (Section 5 paragraph 4)
>
> // Example
> int i = 0;
> ++(++i);    // UNDEFINED

I am a bit puzzled by your post, you quote a part of the standard and
draw some inferences from it.  But you do not add a comment, ask a
question, or propose a change.  What was the point of your post?

C++ has changed the type of the result yielded by some operators
compared to C.  Specifically all the assignment operators and the pre
increment and pre decrement operators all yield an lvalue result.

Presumably this change came about so that overloaded operators for
user defined types could return references and allow many features of
the language to work efficiently.

This decision has consequences, some of them perhaps unanticipated.
If i is volatile, expressions such as ++i or even i = 3 cause
problems.  The fact that the result is an lvalue but the object is
volatile would seem to indicate that lvalue to rvalue conversion must
be performed, resulting in a read of the volatile object after the new
value is written.

But the fact that these operators yield an lvalue is not really
troublesome, and actually not a problem at all with user defined
types.  The pre increment operator for user defined types, as all
operators defined for user defined types, is implemented with function
semantics.  There is a sequence point at the end of the operator
function that occurs before anything the calling code can do to the
lvalue, hence no undefined behavior.

And as to undefined behavior on built-in scalar types, this is already
undefined:

   i = ++i;
   i = i++;

Other than the volatile issue, I don't see a problem.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 3 Mar 2003 05:54:22 +0000 (UTC)
Raw View
On Mon, 3 Mar 2003 03:38:24 +0000 (UTC), jdennett@acm.org (James Dennett)
wrote:

> > ++(++i);    // UNDEFINED

> That is, indeed, undefined.  But

See cwg issue 222.

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Mon, 3 Mar 2003 18:52:24 +0000 (UTC)
Raw View
In article <nO98a.8480$Wl3.847899@newsread1.prod.itd.earthlink.net>,
James Dennett <jdennett@acm.org> writes
>That is, indeed, undefined.  But
>
>int i(0);
>int *p(&++i);
>
>is not; it is an indefensible way of writing
>
>int i(0);
>++i;
>int *p(&i);
>
>It's also legal to write
>
>void f(int &) {}
>
>int main() {
>  int i;
>  f(++i);
>}
>
>which would not be the case if ++i were an rvalue, because
>an rvalue cannot be bound to a non-const reference.
>
>In conclusion: you can use ++i as an l-value, it's just that
>writing to that l-value is undefined.
>
>I think there is some lack of clarity on the standard where
>it should say that using the value of ++i does not constitute
>a violation of other rules, but that doesn't appear to affect
>the issue addressed in your post.

The built in operators divide into two groups, those that return an
rvalue and those that return an lvalue. There are good reasons for
providing the latter but given that the user defined overloads have
sequence points I think we should give serious consideration to
providing the same for the built-in versions. Such a change would not
break a single line of existing code but would remove the potential for
undefined behaviour (particularly nasty if any maintenance programmer
replaces a typedef for a UDT with one for a fundamental type.

This change would also remove one more place where aliasing can bite the
programmer:

void foo(int & a, int & b){
        a = ++b;
}

Note that a good optimiser could still largely remove any overhead
incurred by making operators that return lvalues have sequence points at
the 'return' point.




--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Mon, 3 Mar 2003 18:52:26 +0000 (UTC)
Raw View
In article <jo356vgpb1jeo24jmrovc35beo4ugjsdg7@4ax.com>, Jack Klein
<jackklein@spamcop.net> writes
>And as to undefined behavior on built-in scalar types, this is already
>undefined:
>
>   i = ++i;
>   i = i++;
>
>Other than the volatile issue, I don't see a problem.

Because it is today, does not mean it has to be tomorrow. The question
is whether the optimisations supported by this undefined behaviour
(which were useful in the past) still require that today.


--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow      ACCU

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]