Search code examples
cstdio

C line order reversed by compiler?


I've got this sample code:

#include <stdio.h>
#include <stdlib.h>

int addOne();

int main(int argc, char** argv) {
    char s[100];
    int x = 1;
    x = addOne(x);
    printf("%d",x);
    gets(s);
    return (EXIT_SUCCESS);
}

int addOne(int j) {
    return j + 1;
}

You can see that printf is before gets(s), but when I run the code it asks the string first, after it prints the number. I'm using NetBeans with Cygwin gcc compiler. Is there something I miss? Is it a compiler error?


Solution

  • printf() is usually line-buffered. So printf's output doesn't appear on the screen until the buffer is flushed.

    Add \n to the printf and it should work as expected.

    printf("%d\n",x);
    

    You can disable the buffering if it's not needed using setbuf(stdout, NULL);.

    By the way, you should never gets(). Use fgets() instead. Because gets() is prone buffer overrun vulnerability and has been obsoleted since C99 and has been removed completely from C11.


    Regarding your suspicion that compiler is re-ordering the lines: It's true that compiler can re-order instructions and is allowed to do so legally. But only as long as it doesn't affect observable effect of the program.

    Consider the following code,

    void func(void)
    {
       int a = 2;
       int b = 3;
    
       a = a * 2;  //line 1
       b = b + 3;  //line 2
    
       printf("%d\n", a+b);
    }
    

    Compiler can compute either a or b in any order (line1 or line2) as it wouldn't affect the behaviour of the code. Or it can even simply replace the function with:

    void func(void)
    {
       printf("%d\n", 10);
    }
    

    Typically, compiler would do such transformations for optimization purpose and is allowed. In your code, compiler can't do such code transformations as it would affect the observable behaviour of your code.