为什么gcc会给我这个结果?

时间:2012-02-18 00:12:51

标签: c gcc

当我运行此代码时,gcc给出了输出10。

有人可以向我解释为什么它会给我10个? :)

#include <stdio.h>

int f(int x) {
    int y;
    y = 2*x;
}

int g() {
    int z;
    return z;
}

int main() {
    int x=5;
    f(x);
    printf("%d\n",g());
}

6 个答案:

答案 0 :(得分:6)

这是未定义的行为 - 您正在引用一个没有设置值的变量。可能,它给出了10,因为编译器在f()中对变量使用了相同的内存位置,但是不能保证,它不应该依赖,并且只不过是好奇心。

答案 1 :(得分:3)

没有什么可以解释的。您的代码在两个不相关的不相关的场合展示未定义的行为:首先f没有返回任何内容,尽管被声明为返回int,第二个因为g返回未初始化的值。

实际上,函数放在调用堆栈上的方式会导致本地y(最终值10)与{的返回值处于同一位置在g()调用中{1}},您恰好会看到值printf。但这或多或少都是运气问题。

答案 2 :(得分:2)

下面:

int g() {
    int z;
    return z;
}

这是:

int g():
    reserve memory for an integer, call it z.
    return whatever is in that reserved memory.

你从未对整数使用过保留的内存。它的价值是在您选择使用它之前在该地址上的任何值(或者不使用它,而不是)。这个价值可能是任何东西。

您在其他功能中也这样做。你正在做的是阅读未初始化的记忆。您可以谷歌搜索更多信息。另请参阅“堆栈”和“堆”,动态内存和其他相关主题。

答案 3 :(得分:0)

g从堆栈返回一个未初始化的变量,在你的例子中,该函数最后设置的位置给你的答案是x * 2 = 10

答案 4 :(得分:0)

因为你没有初始化z,所以它在堆栈中使用与y相同的位置。由于你没有初始化它,旧值仍然存在。

答案 5 :(得分:0)

这是一个完美的例子,说明为什么人们担心优化以及他们吹嘘如何向他们的老板发现编译器错误。其他人提到的这段代码将引发有关在g()中使用未初始化变量的警告。使用编译器设置,它在调用f(5)时使用堆栈上的旧值。使用不同的编译器优化设置,它可能会影响变量在堆栈中的结果,并且当您进行看似无关的更改时,最终会得到不同的结果。这是未定义的行为,并且无法保证将产生什么值,但通常很容易通过理解调用顺序以及编译器如何设置堆栈来解释。如果您在排除这样的奇怪行为时有警告,请先修复警告,然后开始询问有关原因的问题。