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

为什么gcc会给我这个结果?,c,gcc,C,Gcc,当我运行这段代码时,gcc给了我10的输出 有人能给我解释一下为什么它给了我10分吗?:) #包括 整数f(整数x){ int-y; y=2*x; } int g(){ intz; 返回z; } int main(){ int x=5; f(x); printf(“%d\n”,g()); } 这是未定义的行为-您引用的变量未设置任何值。很可能,它给出了10,因为编译器对f()中的变量使用了相同的内存位置,但不能保证这一点,它不应该被依赖,只不过是好奇而已。g从堆栈返回一个单位化变量,在您的示例中

当我运行这段代码时,gcc给了我10的输出

有人能给我解释一下为什么它给了我10分吗?:)

#包括
整数f(整数x){
int-y;
y=2*x;
}
int g(){
intz;
返回z;
}
int main(){
int x=5;
f(x);
printf(“%d\n”,g());
}

这是未定义的行为-您引用的变量未设置任何值。很可能,它给出了10,因为编译器对f()中的变量使用了相同的内存位置,但不能保证这一点,它不应该被依赖,只不过是好奇而已。

g从堆栈返回一个单位化变量,在您的示例中,该位置是由F函数最后设置的,该函数给出了x*2=10的答案,无需解释。您的代码在两个不同的、不相关的情况下表现出未定义的行为:第一个
f
尽管声明为返回
int
,但不返回任何内容,第二个原因是
g
返回未初始化的值


实际上,将函数放在调用堆栈上的方式将导致本地
y
(最终具有值
10
)与
printf
调用中的
g()
的返回值位于同一位置,因此您碰巧看到了值
10
。但这或多或少是运气的问题。

因为您没有初始化z,而且它在堆栈上使用与y相同的位置。因为您没有初始化它,所以旧值仍然存在。

此处:

int g() {
    int z;
    return z;
}
内容如下:

int g():
    reserve memory for an integer, call it z.
    return whatever is in that reserved memory.
您从未将该保留内存用于整数。它的价值是在您选择使用它(或者不使用它,更确切地说)之前该地址上的任何内容。这个值可以是任何值


在另一个函数中也可以这样做。您所做的是读取未初始化的内存。你可以用谷歌搜索更多信息。另请参见“堆栈”和“堆”、动态内存和其他相关主题。

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

我认为,在没有-Wall的情况下,永远不应该编译C程序。严格地说,
f()
没有未定义的行为,因为没有使用函数的值。然而,这显然是一个问题。@MichaelBurr:我有一个模糊的想法,“不从非void函数返回值”已经是UB,而不仅仅是以后使用该函数返回值。不过,我得检查一下。和C可能不同于C++在这方面。
int g():
    reserve memory for an integer, call it z.
    return whatever is in that reserved memory.