2

I recently came across a question about sequence points in C++ at this site, about what this code will output:

int c=0;
cout << c++ << c;

It was answered that the output is undefined and << is not a sequence point, but still I want to know why is it undefined when, even if I compile it 25 times, it still always prints 01?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
tushar
  • 307
  • 1
  • 7
  • 17
  • 1
    I think the behavior is merely unspecified. – avakar Apr 12 '10 at 19:17
  • 1
    Link to the original question: http://stackoverflow.com/questions/2603312/the-result-of-int-c0-coutcc – James McNellis Apr 12 '10 at 19:18
  • 8
    Because undefined behavior doesn't *necessarily* mean totally random. – GManNickG Apr 12 '10 at 19:18
  • @avakar: No, undefined. The `c++` and `c` are executed without intervening sequence points. – David Thornley Apr 12 '10 at 19:18
  • This is either subjective and argumentative (because undefined behaviour could be anything so there's no right answer) or an exact duplicate if it's really about whether or not it really is undefined. – CB Bailey Apr 12 '10 at 19:25
  • Duplicate of http://stackoverflow.com/questions/2603312/the-result-of-int-c0-coutcc – David Thornley Apr 12 '10 at 19:25
  • @David: No, that's the question that caused this question. This question is about the nature of undefined behavior, not if that code causes it. – GManNickG Apr 12 '10 at 19:28
  • 1
    @avakar If you think that, please comment on it in the original question - there is a big comment thread on the subject there. –  Apr 12 '10 at 19:30
  • 1
    @avakar: I don't see how it could possibly be unspecified. Either there is a sequence point between the evaluation of `c` and `c++` or there isn't. If there is, the behavior is defined, and "01" is the correct output. If there isn't, the behavior is undefined. – David Thornley Apr 12 '10 at 19:41
  • There is no question about whether the evaluation of `c` and `c++` is unsequenced or not -- it is. What I was missing was 5/4 (which I spent the last 45 minutes searching for, thank you very much), which states "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." So the behavior is indeed undefined. – avakar Apr 12 '10 at 20:08

4 Answers4

8

"Undefined" means that the standard doesn't specify what has to happen in that situation, so anything your compiler does is, by definition, right. If it always prints 01, that's fine. If it prints a different number every time you run, that would be fine too. If it causes monkeys to fly out of your nose (as illustrated here), that would be fine as well.

You might not think so, but the compiler writers are off the hook if it happens.

[Edit: It has been pointed out in the comments that the cannonical reference is "nasal demons", not "nasal monkeys". My apologies for any unintended confusion. Any intended confusion I'm proud of and do not apologize for. :-) ]

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • That made me laugh. +1 to the answer and to the comment. :D – Matteo Italia Apr 12 '10 at 20:04
  • @Gman: lol. Comment was *soo* appropriate, I had to add it to the answer. – T.E.D. Apr 12 '10 at 20:07
  • 1
    @GMan: I am so happy that T.E.D. used "nose" instead of some other body part. – James McNellis Apr 12 '10 at 20:13
  • Lol. Nobody ever believes me that "nasal monkeys" it the actual technical term for this. I believe Stroustrup even talked about it at one point, but I can't find anything on a search anymore. – T.E.D. Apr 12 '10 at 21:06
  • 2
    The original term is "nasal demons", I believe. http://catb.org/jargon/html/N/nasal-demons.html – jalf Apr 12 '10 at 21:21
  • @jalf: Thank you. I know I've seen it as "Nasal monkeys" (I did find an old Unsenet reference to that from 1997), but I guess that person was probably misremembering "nasal demons". – T.E.D. Apr 12 '10 at 21:30
6

You ask:

why does it that even if i compile it 25 times it still prints 01

and the answer is because compilers are basically (but not totally) deterministic - given the same input, they will produce the same output. in terms of machine code. and that machine code is also deterministic, and so always outputs "01". Another C++ compiler though might, in a similarly deterministic fashion, produce machine code that produces "10" every time.

  • Also, a future release of your C++ compiler might change it. I have in the past seen (DEC) compilers that will produce better optimized output if they happen to have more free RAM available when the compiler is run, but that is very rare (and tends to appal exeperienced developers when they hear about it). – T.E.D. Apr 12 '10 at 20:13
  • @T.E.D. Indeed - the RAM thing is precisely the scenario I had in mind when I said "but not totally". –  Apr 12 '10 at 20:14
  • 1
    @T.E.D.: You've got me. I'm indeed appalled. – Donal Fellows Apr 12 '10 at 20:23
  • Some compilers will create binaries with different behavior in regards to UB if you specify different options (such as optimization level). But for a given set of options, I agree that compilers are pretty deterministic. – R Samuel Klatchko Apr 12 '10 at 22:39
  • I had an AIX compiler that would do different behavior between debug and release builds. – EvilTeach Dec 17 '11 at 21:49
5

Because always printing 01 is one of the behaviors your program is allowed to have.

avakar
  • 32,009
  • 9
  • 68
  • 103
1
cout<<c++<<c; 

Let us break this down into its parts:

int c1 = c;        // A
c = c + 1;         // B
int c2 = c;        // C
cout << c1 << c2;  // D

Now, what do we know about the order of these operations? A must be before B, and A & C must be before D. Within those limits, they can be in any order. You may expect them to be executed as A-B-C-D, but they could just as validly be executed as A-C-D-B. Or even C-A-D-B. In fact, it would be legal to execute them as A-(B&C)-D, with B & C executed simulataniously on separate CPUs (which would cause a memory access error, which is why this is undefined and not merely implemention-defined behavior)

James Curran
  • 101,701
  • 37
  • 181
  • 258