3

Some code like this below:

int x = 1;
printf("%d,%d,%d",x,x++,x);  //A  statement
cout<<x<<x++<<x<<endl; //B statement

I know the execute sequence is from right to left,while why A statement result is "1,1,1" and B statement result is "112"???

I use vs2008 with debug mode : the result is same: 2,1,2. with release mode: the result is different: A: 1,1,1, B:1,1,2

guyuequan
  • 75
  • 1
  • 11
  • 7
    Your question tags do a nice job of answering the overall subject for you. – WhozCraig Apr 03 '13 at 05:28
  • *"I know the execute sequence"* Your sure about that? – WhozCraig Apr 03 '13 at 05:29
  • 6
    There are many differences. But in both of these cases, you're invoking undefined behavior. – Adam Rosenfield Apr 03 '13 at 05:29
  • Ditto to @AdamRosenfield s comment. You're effectively violating sequence point rules. – WhozCraig Apr 03 '13 at 05:29
  • 1
    *"I know the execute sequence is from right to left,"* - Do you? That's interesting, since the standard disagrees. – Ed S. Apr 03 '13 at 05:34
  • @CodyGray - Superficially it appears to be a duplicate, but if you read the question, it clearly isn't. This is a question about order of evaluation and sequence points whether the OP realizes it or not. – Omnifarious Apr 03 '13 at 05:37
  • 1
    If you're really interested, [an excellent Q&A on the subject of sequence points](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points). – WhozCraig Apr 03 '13 at 05:38
  • printf is not buffered while std::cout is buffered – Kinjal Patel Apr 03 '13 at 05:50
  • @KinjalPatel: Also wrong. By default, both `print` and `cout` buffer their output (but in separate buffers—don't mix the two!). – Adam Rosenfield Apr 03 '13 at 23:57
  • @AdamRosenfield i know that std::cout is buffered in std::iostream, but never find any information about buffering of printf() – Kinjal Patel Apr 04 '13 at 05:44
  • 1
    @KinjalPatel: See C99 §7.19.3/7: "[...] the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device." – Adam Rosenfield Apr 05 '13 at 04:15

4 Answers4

1

The way you are using printf results in undefined behavior. The order of evaluation of the arguments to a function is unspecified. They do not even have to be evaluated in discreet units at all as parts of one expression can be evaluated and then parts of another. That means if you have certain kinds of dependencies on evaluation order the whole expression can become undefined.

The same goes for calling operator << for cout. << is not a sequence point. The evaluation order for the different clauses of cout there is completely unspecified. And since you have the same kinds of dependencies on evaluation as in the printf example, you are also invoking undefined behavior here as well.

So, you might get the same results for both expressions. You might get different results. Daemons may fly out your nose when you evaluate either of them. You just can't tell.

The topic of sequence points and order of evaluation can be rather complex. I would suggest you take a look at this question if you want to know more:

Community
  • 1
  • 1
Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • It's not undefined behavior, it's unspecified. You're program isn't thrown into an undefined state, but you may not get the result that you expect. – Ed S. Apr 03 '13 at 05:36
  • 3
    @EdS: Yes, it is UB—the commas are not sequence points here (they're function parameter separators, not the comma operator). – Adam Rosenfield Apr 03 '13 at 05:38
  • 1
    @AdamRosenfield: Yeesh, I didn't even think of that, I was focused on argument evaluation order. I really should have seen it after answering 1k+ "why does x++ + ++x not work?" questions. You're right. This bit, however, is wrong - *"The order of evaluation of the arguments to a function is **undefined**."* – Ed S. Apr 03 '13 at 05:38
  • @EdS., It is undefined. We can only be sure that all the arguments have been evaluated _before_ the function is entered. – Anish Ramaswamy Apr 03 '13 at 05:46
  • @EdS., Okay I just read that you mentioned it is unspecified not undefined. Yes. My mistake. – Anish Ramaswamy Apr 03 '13 at 05:52
  • @EdS. - Ahh, I see what you're getting at. Yes, you're right. I've fixed my explanation. The whole thing is undefined, but the order of evaluation of the function arguments is merely unspecified. It's the kinds of dependencies on evaluation order (reading and writing the same variable for example) that render it undefined. – Omnifarious Apr 03 '13 at 06:02
  • @Omnifarious: Yeah, sorry, I could have made that more clear after I realized I completely missed the other issue. – Ed S. Apr 03 '13 at 06:09
0

with the printf, all arguments are evaluated (x=1) before printf is called. with the cout, the arguments are evaluated and applied sequentially. (at least as far as your compiler is concerned)

levis501
  • 4,117
  • 23
  • 25
0

Go through this Article. This is good one.

Duplicate of this Article.

But, Technical if we talk about the printf() or cout<<, While executing printf statement, its takes last statement changed value of the variable, and also affect the changed value to the next statement, rather then current statement.

While in the cout statement, most recent value is taken of the variables, so, its directly affect the current statement.

Hope you ll be clear.

Community
  • 1
  • 1
AB Bolim
  • 1,997
  • 2
  • 23
  • 47
  • 1
    Whilst this may theoretically answer the question, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. This will also help your answer remain useful even if the links you included break in the future. – Cody Gray - on strike Apr 03 '13 at 05:30
  • The title of this question should change, Because its refer the conceptual question rather then technical. – AB Bolim Apr 03 '13 at 05:34
0

Result of statement A and B is same.

        int x = 1;
        printf("%d,%d,%d",x,x++,x);  //A  statement
        //cout<<x<<x++<<x<<endl; //B statement
        return 0;

STATEMENT A

     int x = 1;
    //printf("%d,%d,%d",x,x++,x);  //A  statement
    cout<<x<<","<<x++<<","<<x<<endl; //B statement
    return 0;

STATEMENT B

The result/behavior is inconsistent with compiler.

Ritesh Kumar Gupta
  • 5,055
  • 7
  • 45
  • 71
  • 5
    The result is *sometimes* the same. The use here actually invokes undefined behavior. That means it *might* work the way you want it to, but it might do something else entirely. – Cody Gray - on strike Apr 03 '13 at 05:34
  • I use vs2008 with debug mode : the result is same: 2,1,2. with release mode: the result is different: A: 1,1,1, B:1,1,2 – guyuequan Apr 03 '13 at 06:13
  • 1
    @guyuequan: That's because there is no correct result specified by the standard. You are, in fact, lucky your program doesn't crash or something. – Omnifarious Apr 03 '13 at 06:24