1

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
Undefined Behavior and Sequence Points

Ok we all know that i++ increments value by 1 on next line and ++i increments on same line
(please correct me if i am wrong there )
so for a sample statement of c as follows:

int a=0;  
printf("%d , %d",++a,a);  

the expected output should be 1 , 1 but instead it gives 1 , 0 so as one might guess what i am asking here is why does the second linking of i print 0 instead of 1 when the value is already incremented.

So if post increment didn't increment value in the same line then what is the difference between post and pre increment?
edit : changed the name of variable from i to a to avoid grammatical confusion.

Community
  • 1
  • 1
mOj
  • 27
  • 5
  • `printf("%d,%d",++i,i); ` invokes UB. – Prasoon Saurav Jan 12 '12 at 17:15
  • 3
    The case you've given is an example of undefined behavior. – Nate Jan 12 '12 at 17:15
  • i am not sure what is undefined here , a has been initialized to a perfect int value and i am just testing the increment operator. – mOj Jan 12 '12 at 17:19
  • @mOj - What's undefined is the order in which function arguments are evaluated. – Omnifarious Jan 12 '12 at 17:22
  • This is a very frequently asked question, though hard to look up on SO. Here is a very complete post on the subject: [Undefined Behavior and Sequence Points](http://stackoverflow.com/q/4176328/20984). – Luc Touraille Jan 12 '12 at 17:29
  • here is a quote from that exact post But the following expressions are fine i = (++i,i++,i) // well defined one can see value of a is not modifided twice or more in same statment but just once @ ++a , and it is just printed there so how am i modifying it twice ? also quoted is std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2 so printf("%d%d",i+1,i); is legal ? even though it does not increment i in next line, the rule is not to modify it twice right. So what is the whole point of pre / post increment if it always increments on next line or after ";" ? – mOj Jan 12 '12 at 18:17

5 Answers5

4

You are very wrong in your understanding of the increment operators. i++ increments i, and returns its old value; ++i increments i, and returns the new value. When the actual incrementation takes place is only guaranteed to be after the preceding sequence point, and before the next; in your code, this means before the call to printf.

Beyond that (and largely because of that), if you modify the value of an object, you're not allowed to access it anywhere else without an intervening sequence point, except as needed to determine the new value. You violate this rule, so your code has undefined behavior.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

It's undefined behavior. the compiler is allowed to calculate the parameters in any order. your compiler just calculate it from right to left, so the rightest parameter is 0, and the 2nd is 1.

edit: as Seth said, the compiler is only free to change the order of calculating, not to do whatever it wants, so when you don't care about the order you can freely call functions, but you should never assume that one parameter is been calculated before another.

asaelr
  • 5,438
  • 1
  • 16
  • 22
  • No, the order may be undefined but it's not undefined behaviour. Undefined behaviour is very bad, unspecified behaviour is fine – Seth Carnegie Jan 12 '12 at 17:16
  • 4
    @SethCarnegie: No, *undefined*. C++11, 1.9/10: "If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined." (And the C standard says something similar, in somewhat different language). – Mike Seymour Jan 12 '12 at 17:19
  • @MikeSeymour are you sure there are two side effects here? I can't really make sense of that sentence. `f(i, i++)` seems like it has the first required side effect but not the second side effect (or value computation using that object) required for that definition. Also thanks for the extra correction, I misread. – Seth Carnegie Jan 12 '12 at 17:24
  • @MikeSeymour +1 to Mike, for quoting the new standard. (I and the one other person who gave the right answer based our answers on the old standard. The practical effects haven't changed, but the way they are described has.) – James Kanze Jan 12 '12 at 17:24
  • @SethCarnegie: no, there's one side effect and a "value computation using the value". That's still undefined behaviour. – Mike Seymour Jan 12 '12 at 17:25
  • @SethCarnegie Evaluating the third argument to `printf` is a "value computation using the value of the same scalar object". – James Kanze Jan 12 '12 at 17:25
1

I think your question is not about how increment work. The phenomenon you have observed is about the order of passing parameter to a function. As far as I can remember, this is not defined by c++ standard, so it's a UNDEFINED BEHAVIOR. Meaning different compiler could have different implementation. E.g. One compiler could pass parameter from left to right, then a different could pass parameters from right to left.

You can have a better read of Sequence point here: http://en.wikipedia.org/wiki/Sequence_point

RoundPi
  • 5,819
  • 7
  • 49
  • 75
  • Probably just a question of language, but the order parameters are passed to a function is unspecified, and not undefined behavior. Modifying the value of an object, and accessing the object other than to determine its new value, is undefined behavior unless there is an intervening sequence point. – James Kanze Jan 12 '12 at 17:22
1
printf("%d , %d",++i,i);

is undefined behavior.

Your are violating C sequence points rule:

(C99, 6.5p2) "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored."

ouah
  • 142,963
  • 15
  • 272
  • 331
  • so printing 'i' twice violates the same rule ? – mOj Jan 12 '12 at 17:39
  • @mOj Printing `i` twice like `printf("%d %d", i, i)` ? There is no sequence point violation here, the object `i` is not modified. – ouah Jan 12 '12 at 17:41
1

Once I read in some book that when a statement is like this:

printf("%d , %d",++a,a);

The execution starts from right to left but outputted as left to right. Therefore you see the out as 1 0 - 'a' is calculated first = 0 then '++a' = 1, but displayed as 1 0

This is strange but yeah that's how it works.

Hope this helps.

shrishaster
  • 682
  • 9
  • 21