Search code examples
cgccstructclangscoping

Scoping rules for struct variables in GCC


Consider the following C program

#include <stdio.h>

typedef struct s {
  int x;
} s_t;

int main() {
  int x;
  s_t a;

  scanf("%d", &x);

  if (x > 0) {
    s_t a;
    a.x = x;
  }

  printf("%d\n", a.x);
}

The a struct variable in the if branch clearly shadows the a struct variable in main. One would expect that the output in printf would be undefined, but with GCC the scoped variable seems to equal the main variable.

For example

gcc test.c -o test
echo 10 | ./test

will output 10.

On the other hand, running this through clang, does as expected

clang test.c -o test
echo 10 | ./test

outputs -2145248048.

Is this a GCC bug or is there some sort of undefined behaviour that this is triggering?

gcc 4.8.2 clang 3.4


Solution

  • As others mentioned, you're reading an uninitialized local variable and that's undefined. So, anything is legit. Having said that, there is a particular reason for this behavior: gcc reuses variables on the stack as much as it can (i.e., as long as the generated code is provably correct). You can fine-tune using the -fstack-reuse option.

    To disable stack reuse:

    gcc test.c -o test -fstack-reuse=none
    echo 10 | ./test
    4195808 # prints some random number.
    

    To enable stack reuse for all variables:

    gcc test.c -o test -fstack-reuse=all  #, or -fstack-reuse=named_vars
    echo 10 | ./test
    10 # prints 10, as it reuses the space on the stack.
    

    This is fully documented on GCC Code Generation Options.