Checking rules for structured variables in GCC

Consider the following program C

#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 structured variable a

in the if branch clearly highlights the structured variable a

in the main. One would expect the output in printf to be undefined, but with GCC the visible variable seems to be equal to the main variable.

for example

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

      

will output 10.

On the other hand, doing this through clang as expected

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

      

outputs -2145248048.

Is this a GCC bug or is there some undefined behavior that gets triggered?

gcc 4.8.2 clang 3.4

+3


source to share


4 answers


As mentioned, you are reading an uninitialized local variable and undefined. So everything is legal. Having said that, there is a special reason for this behavior: gcc

reuses variables on the stack (for example, until the generated code is plausible). You can make fine adjustments using the parameter -fstack-reuse

.

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 described in GCC Code Generation Options .

+9


source


One would expect the output in printf to be undefined

It's undefined. Undefined behavior means that something can happen, including (but not limited to) any particular output.



In this case, it is likely that the compiler will optimize both a

to have the same address.

+4


source


Compiler error, your program is calling undefined behavior.

You are reading an uninitialized automatic object and C says it is undefined, and reading is undefined behavior.

Give a.x

(declared in scope main

) a value to give your program specific behavior.

+4


source


Is this a GCC bug or is there some undefined behavior that gets triggered?

This behavior is undefined. s_t a;

in the statement if

hides the previous declaration a

.
In the block

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

      

x

assigned to local a.x

. After this block is a

no longer available, and in printf

you you get access to an uninitialized variable. Uninitialized variables can call UB.

+3


source







All Articles