7

Possible Duplicate:
cout << order of call to functions it prints?
Undefined Behavior and Sequence Points

Why does this code print 2 1 0?

#include <iostream>
struct A{
  int p;
  A():p(0){}
  int get(){
    return p++;
  }
};


int main(){
 A a;
 std::cout<<a.get()<<" "<<a.get()<<" "<<a.get()<<std::endl;
}
Community
  • 1
  • 1
Fabio Dalla Libera
  • 1,297
  • 1
  • 10
  • 24
  • 2
    There's no sequence point... §6.2.2 __The order of evaluation of subexpressions within an expression is undefined.__ – obataku Aug 23 '12 at 06:41
  • THank you, this seems to be the reason, confirmed in http://stackoverflow.com/questions/3463261/operator-precedence-for-and-in-vs2008-with-optimization?rq=1 Please make your comment an answer, I will mark it as final – Fabio Dalla Libera Aug 23 '12 at 06:42
  • I have posted my comment as an answer :-) – obataku Aug 23 '12 at 06:44

1 Answers1

4

As I stated in my comment, there's no sequence point...

According to §6.2.2 of Stroustrup's The C++ Programming Language, Third Edition...

The order of evaluation of subexpressions within an expression is undefined. In particular, you cannot assume that the expression is evaluated left to right.

§5.4 of the C++03 standard specifies:

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. 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.

You can learn more about sequence points and undefined behavior here.

Community
  • 1
  • 1
obataku
  • 29,212
  • 3
  • 44
  • 57
  • 2
    Where does your citation come from? I looked in C++03, C++11, C90, C99 and C11 and none have a 6.2.2 with that content. BTW, C++03 in 5/4 says "Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is **unspecified**." (and the version I'm using has change mark from C++98, so that has probably not changed). The difference with **undefined** is that the code has to provide one of several results and may not start to launch a fleet of daemons out of your nose. – AProgrammer Aug 23 '12 at 06:56
  • Stroustrup's *The C++ Programming Language*, particularly the 3rd edition. ***The order of evaluation of subexpressions within an expression is undefined. In particular, you cannot assume that the expression is evaluated left to right.*** – obataku Aug 23 '12 at 07:02
  • By the way, I don't think your point about the difference between *unspecified* and *undefined* in this context holds any weight, given an *undefined* evaluation order between sequence points just means it can be done however the environment wishes for it to be done -- i.e. the same as *unspecified*. The order is unspecified giving rise to undefined behavior :-) – obataku Aug 23 '12 at 07:06
  • There are plenty of sequence points in the expression - however the order of evaluation is unspecified. Sequence points and order of evaluation are two concepts which are different, even if they're related in some ways (sequence points sometimes influence order of evaluation). – Michael Burr Aug 23 '12 at 07:19
  • 3
    The standard makes a strict difference between unspecified order (some order, but we don't know which), and undefined behavior (*anything* can happen). Stroustrup seems to be less strict in his book. – Bo Persson Aug 23 '12 at 07:26