C:全局变量和局部变量同名

C: Global variable and local variable of same name

代码:

#include <stdio.h>

int var = 20;
int main()
{
   int var = var;
   printf("%d\n", var);
   return 0;
}

GCC 在此代码中输出垃圾值。我的疑问是,这应该输出“20”。

说明: 每当我们为任何 global/local 变量赋值时,计算机的第一条指令是将赋值保存到寄存器中,然后将其放入内存中。因此,根据我的说法,当编译器遇到 "int var = var" 时,它应该首先将值 20 保存到特定的寄存器中。然后将其保存到局部变量。然后在全局变量应该超出范围之后。 是的,这与变量名称先赋值而不是值赋值的说法相矛盾。所以,int var 使得全局 var 变量超出作用域,让局部变量自己赋值,相当于未初始化的局部变量。

int var = var;

是未定义的行为。它是带有未初始化值的自我赋值。

在 C 和 C++ 中,变量的作用域在声明后立即开始。因此,当读取 var 的值以将其分配给 var 时,本地 var 已经在范围内。

讨论寄存器和内存等等有点跑题了; C 是一种标准化语言,其行为由标准规定。

首先var是一个全局变量。它的 初始化的。第二个是本地的。它刚刚被声明,and 编译器认为,=var 试图将 something (没有价值,只是垃圾)分配给 本地变量.

全局变量被局部变量覆盖。

int var = var 

第二个"var"没有引用全局变量,所以var是未初始化的变量,所以它的值是垃圾

在 C++ 中有术语声明点。尽管在 C 中不使用这样的术语,但实际上定义标识符声明点的规则在 C++ 和 C 中是相同的。

我将引用 C++ 标准中对 C 有效的引用。

因此

1 The point of declaration for a name is immediately after its complete declarator

所以在你声明的例子中

int var = var;

声明左侧的declarator var隐藏了同名的全局变量。结果变量 var 被自己初始化并且具有不确定的值。

C++ 标准中的另一个例子

2 [ Note: a name from an outer scope remains visible up to the point of declaration of the name that hides it.[ Example:

const int i = 2;
{ int i[i]; }

declares a block-scope array of two integers. —end example ] —end note ]

对于枚举

5 The point of declaration for an enumerator is immediately after its enumerator-definition.[ Example:

const int x = 12;
{ enum { x = x }; }

Here, the enumerator x is initialized with the value of the constant x, namely 12. —end example ]

编译器在比全局 var 的范围最近的范围(本地)中找到了 var。 您正在将局部变量的值赋给自身,并且它未初始化。