简体   繁体   English

为什么gcc给我这个结果?

[英]Why does gcc give me this result?

When I run this code gcc gives me the output 10. 当我运行这段代码时,gcc给我输出10。

Can someone explain to me why it gives me 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());
}

this is undefined behavior - you are referencing a variable which has no value set to it. 这是未定义的行为-您引用的变量没有设置值。 likely, it gives 10 because the compiler has used the same memory location for the variable in f(), but there is no guarantee of that, it should not be depended on, and is nothing more than a curiosity. 可能会给出10,因为编译器在f()中为变量使用了相同的内存位置,但是并不能保证一定不能依赖它,也只是出于好奇。

There's nothing to explain. 没有什么可解释的。 Your code exhibits undefined behaviour on two separate, unrelated occasions: First f isn't returning anything despite being declared as returning int , and second because g returns an uninitialized value. 您的代码在两个独立的不相关的情况下表现出未定义的行为:第一个f尽管被声明为返回int ,但未返回任何内容;第二个因为g返回了未初始化的值。

Practically, the way the functions will be put on the call stack will have caused the local y (which eventually has the value 10 ) to be in the same place as the return value of g() in the printf call, so you happen to see the value 10 . 实际上,将函数放置在调用堆栈上的方式将导致局部y (最终值为10 )与printf调用中g()的返回值位于同一位置,因此您碰巧参见值10 But that's more or less a matter of luck. 但这或多或少是个运气问题。

Here: 这里:

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

This reads: 内容为:

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

You never used that reserved memory for your integer. 您从未将保留的内存用于整数。 Its value is whatever was at that address before you chose to use it (or not use it, rather). 它的值就是您选择使用(或不使用它之前)该地址上的值。 That value could be anything. 该值可以是任何值。

You do the same in your other function. 您可以在其他功能中执行相同的操作。 What you are doing is reading uninitialized memory. 您正在做的是读取未初始化的内存。 You can google that up for further information. 您可以在Google上搜索更多信息。 See also the "stack" and the "heap", dynamic memory, and other related topics. 另请参见“堆栈”和“堆”,动态内存以及其他相关主题。

g从堆栈中返回一个单位化的变量,在您的示例中,位置最后由F函数设置,给您x * 2 = 10的答案

Because you're not initializing z, and it's using the same location on the stack as y. 因为您没有初始化z,并且它在堆栈中使用的位置与y相同。 Since you're not initializing it the old value is still there. 由于您没有初始化它,所以旧值仍然存在。

This is a perfect example of why people fear optimizations and when they brag about finding compiler bugs to their bosses. 这是一个很好的例子,说明了人们为什么害怕优化以及何时向老板吹嘘寻找编译器错误。 This code as others have alluded to will throw warnings about using uninitialized variables in g() . 正如其他人所暗示的,此代码将发出有关在g()使用未初始化变量的警告。 With your compiler settings, it is using the old value on the stack from the call to f(5) . 使用您的编译器设置,它将使用从调用f(5)开始的堆栈上的旧值。 With different compiler optimization settings, it will likely have effects on how variables end up on the stack and you'll end up getting a different results when you make changes which appear unrelated. 使用不同的编译器优化设置,可能会影响变量在堆栈中的存储方式,并且当进行不相关的更改时,您将最终获得不同的结果。 This is undefined behavior and there is no guarantees on what value will result however it is usually easy to explain by understanding the call order and how the compiler sets up the stack. 这是未定义的行为,无法保证会得到什么值,但是通常可以通过了解调用顺序和编译器如何设置堆栈来轻松解释。 If there are warnings when you're troubleshooting weird behavior like this, fix the warnings first then start asking questions about why. 如果在对此类怪异行为进行故障排除时出现警告,请首先修复警告,然后开始询问原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM