Topic: mutiple ++ operators in same expressio


Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/05/04
Raw View
In article 1@nnrp1.dejanews.com, asbinn@rstcorp.com writes:
>In article <6iff8g$i8q@engnews1.Eng.Sun.COM>#1/1,
>  clamage@Eng.Sun.COM (Steve Clamage) wrote:
>>
>> The sample code looked like this:
>>
>> >output   : command (or parial cmd) that generated the output
>> >---------:----------------------------------------------------------
>> >(3,3,3)  :  Vector3f a(atof(str[++i]), atof(str[++i]), atof(str[++i]))
>>
>> The code attempts to modify a variable more than once between
>> sequence points, and so the behavior is undefined. That has
>> always been the case in C, and is still the case in C++.
>
>I thought that this example yields unspecified behavior, not undefined
>behavior.  The reason is the unspecified order of function argument
>evaluation.  Isn't there a sequence point after each call to atof()
>(assuming that atof() is a function call and not a macro) [intro.execution
>p17]?  If so, then 'i' isn't modified more than once between sequence
>points.

The issue is subtle and requires more explanation.

There is indeed a sequence point after evaluating the arguments to a
function and before it is called, and another one upon return from
the function. But the commas in the parameter list are not sequence
points. Let's consider a more general case:
 f( g(e1), h(e2) )
where f, g, and h are functions, and e1 and e2 are general expressions.

All the side effects of e1 must be complete before g is called, and
all the side effects of e2 must be complete before h is called, but
that provides only a partial ordering.

There is no sequence point between e1 and e2. For example, their
evaluations can be interleaved, and their side effects can be completed
in any order and at any time before their functions are called. In that
respect, the situation is no different from
 f( e1, e2 )

Thus, if e1 and e2 attempt to modify the same variable, the results
are undefined in both cases.

>Whether or not the behavior is classified as undefined or unspecified
>is probably of little consequence to most programmers, as relying on either
>one will lead to unreliable programs.

Yes. "Undefined" might be a bit too strong to describe the situation,
but "unspecified" is too weak. "Unspecified" usually means that a
well-defined set of options is available and the implemenation must
choose one of them. That isn't really the case in general when multiple
modifications to variables can occur. Rather than trying to describe
what might happen, the C and C++ standards just say "anything might
happen", which is what "undefined behavior" means.

---
Steve Clamage, stephen.clamage@sun.com


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]