0

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

#include<stdio.h>
void main()
{
int a=5;
printf("%d\t%d\t%d\n",a,a++,++a);
}

Output of the above program showing 7 6 7 in gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5). Why it is showing instead of 7 6 6 ?

Community
  • 1
  • 1
Javad Shareef
  • 496
  • 7
  • 18
  • 1
    The behavior of the program is undefined because the return type of `main()` must be `int`. – James McNellis Jun 29 '12 at 18:24
  • @JamesMcNellis: that's not the only undefined behaviour. – Jonathan Leffler Jun 29 '12 at 18:24
  • 1
    See [`Undefined Behavior and Sequence Points`][1] [1]: http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Jack Jun 29 '12 at 18:25
  • @JonathanLeffler: I know, but with this question, I also know that at least six people will answer it or provide links to other similar questions :-) – James McNellis Jun 29 '12 at 18:25
  • @JonathanLeffler:It's not a UB. Moderns compiler converts `void main()` to `int main()` by default. Also, the return-value of main function don't intefere anyway on execution of program itself. – Jack Jun 29 '12 at 18:38
  • I changed the program into #include int main() { int a=5; printf("%d\t%d\t%d\n",a,a++,++a); return 0; } But I am getting same output again. – Javad Shareef Jun 29 '12 at 19:09
  • The theoretical answer ('it is undefined behaviour') includes the option 'it will behave semi-sanely and the same way regardless of the type of `main()`'. All you know is that the compiler may do as it wishes, and you cannot complain about what it does because the behaviour is undefined. If you want defined behaviour (and you almost always _do_ want defined behaviour), you have to revise your code to give the answer you want, rather than whatever answer the compiler happens to decide to give you. – Jonathan Leffler Jun 29 '12 at 19:16
  • @JonathanLeffler Thank you for your detailed explanation. Am happy with your answer and will do more study on this. – Javad Shareef Jun 29 '12 at 19:21

3 Answers3

4

Your program can show anything it likes and the output is correct.

The behaviour is undefined; anything is allowed to happen.

What's undefined?

  • Incrementing a twice in the argument list to printf().

The behaviour of void main() is at best implementation-defined. The return type of main() should be int.


ISO/IEC 9899:2011 (C 2011) Standard

§ 6.5 Expressions

¶2 If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

84) This paragraph renders undefined statement expressions such as

    i = ++i + 1;
    a[i++] = i;

while allowing

    i = i + 1;
    a[i] = i;
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I don't get it, why when I test this program, with a int value returned from the main and the good parameters in it I get : 7 6 7? – Jeremy D Jun 29 '12 at 18:28
  • You could get 'pink elephants' as the printed information and it would still be valid (though rather implausible). There is no guarantee in the language about what will be produced. There is no sequence point while the arguments are being evaluated; the commas in the argument list are not comma operators. There is a sequence point when the arguments are all evaluated and before the function is called; there is another sequence point before/as the function returns. But while the arguments are evaluated, anything is OK. Changing the optimization could change the result; that is OK, too. – Jonathan Leffler Jun 29 '12 at 18:33
  • Is operator precedence plays any role in the output that is pre-increment and post increment? – Javad Shareef Jun 29 '12 at 19:05
  • @javad_shareef: no; operator precedence has no effect on the result when the pre-increment or post-increment operators are used multiple times on the same variable between a pair of sequence points. – Jonathan Leffler Jun 29 '12 at 19:12
  • @JonathanLeffler: I changed the void into int and compiled same program. But it is showing same out put. I tried the same program with Turbo C compiler, but it showing some other output. – Javad Shareef Jun 29 '12 at 19:18
  • See my comment to the main question. Turbo C can do what it likes; different versions of GCC can each do what they like. Other compilers can do other things. The use of `void main()` is only valid if your compiler documents it as valid. GCC will complain (at least if it is encouraged to give warnings); it does not document `void main()` as valid. I'm not remotely convinced by the 'a modern compiler converts `void main()` into `int main()`' thesis. – Jonathan Leffler Jun 29 '12 at 19:20
  • The order in which the expressions `a`, `a++`, and `++a` are evaluated, and the order in which their side effects are applied, is **unspecified**; the compiler may evaluate them in any order it feels like (and this order may change from call to call). Because of this, you will get different results for different compilers (or even the same compiler with different optimization settings). The behavior is left **undefined** so that the compiler isn't under any obligation to "do the right thing", whatever that may be. – John Bode Jun 29 '12 at 19:52
1

Modifying the same variable more than once in one statement in undefined in C. You should avoid doing that, because the results are unpredictable, and may very between compilers.

Oleksi
  • 12,947
  • 4
  • 56
  • 80
-1

A simple explanation for the difference between "a++" and "++a" is this:

With "a++", the increment is dont after the operation and "++a" is done before the operation.

For example:

a = 0; print("%d ", a++); printf("%d ",a); would give you 0 1.

a = 0; print("%d ", ++a); printf("%d ",a); would give you 1 1.

Steven Luu
  • 1,047
  • 1
  • 7
  • 13
  • Doesn't really answer the question. It is not about the difference between preincrement and postincrement – Dan F Jun 29 '12 at 18:30
  • That is not the cause of this behavior. It's because the C standard does not defined an order of evaluation; the expression can be evaluated from right-to-left or left-to-right; it's the cause of differents results on differents C compilers. The compiler writer is free to handling it as want. The link that I've pointed on comments has a great explanation about this. – Jack Jun 29 '12 at 18:32