-1
#include<stdio.h>

void bar()
{
 int a=4;
}
void foo()
{
 int a;
 printf("%d",a);
}
int main()
{
 bar();
 foo(); 
}

我确信上面的程序将输出作为一些垃圾值(这就是我编译和运行时发生的事情)。但是我在一篇文章中读到,某些编译器可以将输出本身设为 4。给出的解释是它与激活堆栈和激活帧有关。我不明白。是否类似于 bar() 函数中的 int a=4 的值存储在激活堆栈中的某个位置以供将来使用?我很困惑!

4

4 回答 4

3

不要担心某些编译器可能会做什么。它被称为“未定义的行为”。始终确保将变量初始化为您想要的任何值。

所以再一次,试图“理解”是没有意义的,因为没有逻辑,这当然不是“预期的行为”。但是,可以想象,如果函数是内联的,一些编译器会在 cpu 上重用一个寄存器,所以是的,它可能会发生。如果你担心有人在你之后运行一个函数并“窃取你的价值”,那么在退出你的函数之前将其设置为零。但这不是“最佳实践”。

换句话说,即使第二个函数使用'b'而不是a,如果它们重用内存空间,它也可能有4。或者其他一些编译器实际上可能按字母顺序预先分配,所以只有“a”可以工作。同样,这是未定义的行为。

于 2013-10-23T18:31:58.993 回答
1

函数foo使用未初始化的变量。在这种情况下,编译器可以自由地做它喜欢的事情。在实践中,您可能会在现已失效的帧中获得先前放置在堆栈中的变量。正如你所说,它可以是 4,但也可以是其他任何东西。永远不要依赖这种行为……它可能是 99% 可靠的,但在第 100 次尝试时就会出错。

于 2013-10-23T18:33:47.597 回答
1

需要明确的是, foo's a 最终可能会在其中设置 4 (与它们具有相同名称的 BTW 无关)。但这高度依赖于编译器机器等。

你实际上在做什么(在 foo 中)是“未定义的行为”,你使用 a 而不给它一个值。未定义意味着编译器可以做任何事情,格式化你的硬盘,打印任何随机值,包括你最好的朋友的生日,或者它可以打印 4。

为什么可能是 4,因为在许多系统上构建堆栈帧的方式会导致 bar 将 4 写入地址并 foo 将其读回。这两个函数具有相同的参数、返回类型和局部变量的数量,因此第一个局部变量可能会分配在相同的内存位置。这就是为什么你读到它们可能具有相同的值,但这是偶然的,而不是设计使然

顺便说一句,你有没有得到 4,可能没有

于 2013-10-23T18:40:35.530 回答
0

尽管这两个变量具有相同的名称,但它们存储在不同的地址中,并且a由编译器初始化的第二个变量的值可能不是 4。

这里看起来像a,但是一旦编译,这两个局部变量是不同的,不能相同。

于 2013-10-23T18:29:06.153 回答