-1

While the run the below program in Turbo C compiler, I am getting the expected output, however, when I run the same program it using "gcc" compiler in linux, it is giving an unexpected output!

int main(){

    int i=1;

    i=2+2*i++;
    printf("i : %d\n",i);

    return 0;
}

Output in Turbo C => i : 5 (This is as expected!)
Output in GCC => i : 4 ( Why is the post increment ignored in this case?)

Can someone please explain what exactly happens in the compilation process?

  • 7
    Basically your problem is invoking undefined behavior, i.e. i = i++; cannot be expected to have any particular result. See here stackoverflow.com/questions/949433/… – Brandin Jul 7 '15 at 19:05
  • Just to confirm, is it undefined in gcc compiler or c language grammar ? – crown679 Jul 7 '15 at 19:13
  • 6
    Undefined means the language standard does not say what will happen. You said you were "expecting" Turbo C's answer, but this is wrong. Ideally, the implementation should warn you that you're doing something silly with such expressions. Try compiling with a compiler newer than Turbo C with all instrumentation (aka "warnings") turned on. – Brandin Jul 7 '15 at 19:23
  • 2
    The real question is why are you using Turbo C; an ancient, nonstandard, utterly crappy compiler? – user22815 Jul 8 '15 at 1:11
  • 4
    I'm voting to close this question as off-topic because it is about a specific of tool use and undefined behavior and should instead be asked on Stack Overflow, but would be closed as a duplicate of Why are these constructs (using ++) undefined behavior? – user40980 Jul 8 '15 at 2:50
2

As others commented, this i=2+2*i++; is undefined behavior. Please read the wikipage explaining it.

See this answer to understand a bit more about UB.

Then read Chris Lattner's blog entries What Every Programmer should know about Undefined Behavior.

To understand the actual behavior of your buggy C program, you need to dive into implementation details (and you don't want to). If you really want to understand what has happened when using GCC, you might compile your badub.c program with gcc -fdump-tree-all -O -fverbose-asm -S badub.c and then lose weeks of your time understanding the (hundreds) of badub.* files that this compilation command produced. Is it worth your time?

The lesson is avoid UB at all cost

To help more about avoiding UB, recent GCC compilers are sometimes able to emit warnings about it. You should at least compile with gcc -Wall -Wextra -g to get all warnings and debug info. Learn to use the debugger. Learn about various -fsanitize= options to recent GCC. Learn and use valgrind

BTW, it is the year 2015. Don't use TurboC, which is non-standard compliant, not efficient, not giving good warnings, buggy, proprietary, compiler of the previous century. Use a good free software compiler (like recent GCC or Clang/LLVM. Both can give better code and better warnings -when asked to- than your old crappy TurboC...)

  • Using GCC with -Wall -Wextra will warn on the OP's problem, but I don't see how valgrind would help you with this one. – Brandin Jul 8 '15 at 18:46
  • It will help with the next OP's problem – Basile Starynkevitch Jul 8 '15 at 19:03
1

3 things are happening:

  1. The value of i is being read into a register, call it R

  2. 2+2*R is being stored into i

  3. R+1 is being stored into i.

The tricky thing is that you are not guaranteed that #2 will happen before #3, or that #3 will happen before #2. This is an example of undefined order of operations.

Not the answer you're looking for? Browse other questions tagged or ask your own question.