1

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

Code 1:

   main()
  {
   int a=5;
   printf("Value : %d %d %d %d\n",a++,a++,++a,a++);
  }
  ANS:
  Value : 8 7 9 5

Code 2:

   main()
  {
   volatile int a=5;
   printf("Value : %d %d %d %d\n",a++,a++,++a,a++);
  }
  ANS:
  Value : 8 7 7 5

Code 3:

   main()
  {
   int a;
   scanf("%d",&a);
   printf("Value : %d %d %d %d\n",a++,a++,++a,a++);
  }
  INPUT is 5
  ANS:
  Value : 8 7 7 5

How the above programs are getting different outputs ?

I experimented volatile variable , it is used to prevent compiler optimizations. So I understood the Code 2. But I want to know that ,how the Code 1 and 3 are working ?

Community
  • 1
  • 1
RoCkStUnNeRs
  • 301
  • 1
  • 4
  • 9
  • 4
    The order of evaluation of function arguments is unspecified, so your increments can be done in any order. The compiler can produce a number of different results, depending on what it feels like. – Thomas Padron-McCarthy Sep 24 '12 at 07:23
  • 1
    The behavior is undefined for reasons that are explained [here](http://stackoverflow.com/questions/949433/). Adding the `volatile` keyword doesn't change that. – Keith Thompson Sep 24 '12 at 07:42
  • A complication is that modifying *the same* variable more than once in the same expression is undefined behavior. **Anything** can happen. – Bo Persson Sep 24 '12 at 07:43
  • 2
    @ThomasPadron-McCarthy: It's not just a matter of the evaluation order being unspecified. There are 24 possible evaluation orders for the 4 relevant arguments, but the possible behaviors are not limited to those 24 possibilities. The behavior is completely *undefined*, not merely *unspecified*. – Keith Thompson Sep 24 '12 at 07:43
  • @BoPersson: The behavior is undefined when the same variable is modified more than once *between consecutive sequence points*. It's possible to have sequence points within an expression; `i++ && i++` is well defined, for example. – Keith Thompson Sep 24 '12 at 07:45
  • @Keith - Ok, I might have written "in this expression", but didn't want to introduce sequence points to the OP. – Bo Persson Sep 24 '12 at 07:49
  • 3
    As a former member of X3J11, I find this pedanticism that treats UB as a license to blow up the world quite tiresome. All UB means is that no behavior by the implementation disqualifies it as a conforming implementation as defined by the standard; it doesn't mean that there aren't numerous other constraints on what implementations will in fact do. Nowhere in any compiler is there a test to see whether something is UB and, if so, take arbitrary or rash action. – Jim Balter Sep 24 '12 at 07:53
  • 1
    @Jim - But there are optimizers (in g++ for example) that take UB into account and remove code that cannot be reached in a correct program. This can lead to crashes, or worse. – Bo Persson Sep 24 '12 at 08:03
  • They don't take UB into account, they take the lack of a constraint in the standard into account. Another point about stuff like "it could wipe out your disk drive": any implementation **can** wipe out your disk drive even if your program is a conforming C program that does not, by C semantics, wipe out disk drives. It simply means that the implementation is not conforming. There is no magic powers in the C standard that can make an implementation conform ... it's just something that implementers strive to do, just as they strive not to wipe out your disk drive for no good reason. – Jim Balter Sep 24 '12 at 08:07
  • And if code cannot be reached in a correct program, then it would only be reached by virtue of UB, and the UB can cause a crash, so a crash resulting from removing code is moot. – Jim Balter Sep 24 '12 at 08:12

3 Answers3

1

volatile is to tell the compiler to read the value from memory every time as opposed to do any caching of values as part of its optimizations.

Your code exhibits undefined behaviour which is not going to be changed in anyway by using volatile.

P.P
  • 117,907
  • 20
  • 175
  • 238
1

What you have is an Undefined Behavior.
Your code modifies a variable more than once without an intervening sequence point.
You cannot use this code to draw any conclusions. It assures only one thing: that the output is Undefined.

This answer of mine explains in detail why this is undefined behavior. Note that though the answer is for C++, exact same reasoning and specifications exist for C as well.

what is the difference between volatile and local variable in c?

Using the keyword volatile tells the compiler to restrain from any optimizations by use of register caches.

Good Read:
Herb Sutter's excellent artile "volatile vs. volatile"

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

It's undefined behavior. No one can predict the correct output of the

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

which one is executed first whether a++ or ++a so it's different output for different compiler or different scenarios.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
Omkant
  • 9,018
  • 8
  • 39
  • 59
  • Because order of evaluation of argument in a fuction is undefined – Omkant Sep 24 '12 at 07:24
  • 2
    @JeroenMoons They're all *"executed"* (given you mean *evaluated*) **before** the actual `printf` call in an unspecified order. It's only their return values that differ, but that's irrelevant because at that point the UB is already done. – Christian Rau Sep 24 '12 at 07:28
  • The order is merely unspecified, but it is undefined behavior to modify *the same* variable more than once. – Bo Persson Sep 24 '12 at 07:41
  • @Christian I stand corrected, early in the morning here ;) – Asciiom Sep 24 '12 at 08:10
  • 1
    @JeroenMoons pre- and post- increment have nothing to do with *when* the operation is performed, they only determine the *value* of the expression: The value of `++a` is `a0+1` and the value of `a++` is `a0`, where `a0` is the value of `a` before the expression is evaluated. The side effect of actually changing the value of `a` can happen at any time between sequence points bounding the expression. – Jim Balter Sep 24 '12 at 08:18
  • @Jim Isn't the value of the expression `a++` equal to a0 then at the time it is evaluated for the printf call? – Asciiom Sep 24 '12 at 08:24
  • 1
    @JeroenMoons Not necessarily, because there is no sequence point during argument evaluation, so the value of `a0` may be the value of `a` after any of the other arguments are evaluated -- it's indeterminate. And since it is indeterminate, it is undefined according to the C standard. (Which does not mean that it's a license for the implementation to wipe your hard drive.) – Jim Balter Sep 24 '12 at 08:30
  • @JimBalter Ok, now I'm following, thanks for your clarification! – Asciiom Sep 24 '12 at 08:34