c - GCC 中结构变量的作用域规则

标签 c gcc struct clang scoping

考虑以下 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);
}

if 分支中的 a 结构变量明显隐藏了 main 中的 a 结构变量。人们会认为 printf 中的输出是未定义的,但对于 GCC,作用域变量似乎等于主变量。

例如

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

将输出 10。

另一方面,通过 clang 运行它,会按预期进行

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

输出 -2145248048。

这是 GCC 错误还是触发了某种未定义的行为?

海湾合作委员会 4.8.2 clang 3.4

最佳答案

正如其他人所提到的,您正在读取一个未初始化的局部变量并且它是未定义的。所以,任何事情都是合法的。话虽如此,这种行为有一个特殊的原因:gcc 尽可能多地重用堆栈上的变量(即,只要生成的代码可证明是正确的)。您可以使用 -fstack-reuse 选项进行微调。

要禁用堆栈重用:

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

为所有变量启用堆栈重用:

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.

这在 GCC Code Generation Options 上有完整记录.

关于c - GCC 中结构变量的作用域规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30854828/

相关文章:

python - 为什么这个函数在一些更大的变量值上得到错误的结果

c - 是否可以在自定义结构上使用作用于 FILE* 的函数?

c - GCC 输出目标文件与源文件位于同一目录中

c - GCC 程序未定义对函数的引用(多个文件夹)

c++ - 使用 C 和 C++ 绑定(bind)链接到库

c++ - 可变大小结构 C++

c++ - 安全段错误?

c - 为什么 C List Pop 在第一次运行时不起作用?

c - 打印结构字段多次只打印最后一个元素 - C

c# - C#中Int32的扩展方法