我不确定为什么在f()的第二次运行中,i被设置为1234?我认为当第一个f()被执行以完成时,第一个f()的堆栈框架将被"弹出",我认为这意味着i现在是一个不可预测的值.对于调用g(5432)之后的第三个f()函数调用也是如此.为什么i突然变成了5432呢?

 void f();
 void g(int);
 
 void main() {
     f();
     f();
     g(5432);
     f();
 }
 
 void f() {
     int i;
     printf("%d\n", i);
     i = 1234;
 }
 
 void g(int val) {
     printf("%d\n", val);
 }

以下是我在运行代码时得到的输出:

0
1234
5432
5432

推荐答案

这是undefined behavior美元的行动.

因为您读取的是一个以f为单位的未初始化变量,所以当您这样做时,不能保证程序的行为.事实上,如果您在启用优化的情况下进行编译,您可能会看到不同的行为.

话虽如此,以下是可能发生的事情.

虽然函数的堆栈框架确实在函数返回后被"弹出",但调用另一个函数通常会使用与前一个函数调用相同的堆栈空间.没有发出任何将前一个堆栈帧中使用的值清零的指令,因此您最终看到的是以前恰好在那里的值.

在多次调用f的情况下,局部变量i在每次调用中都位于堆栈的同一位置.在g的情况下,没有局部变量,但传递的参数在堆栈中的位置与f中的i相同.

但同样,也不能保证这种行为.如果我在没有优化的情况下编译您的代码,我会得到与您相同的输出,但如果我用-O1编译,我会得到以下输出:

0
0
5432
0

C++相关问答推荐

从C函数调用asm函数时生成错误的BLX指令(STM32H753上的gcc)

如何设置指针指向在函数中初始化的复合文字中的整数?

手动矢量化性能差异较大

ZED for SDL上的C语言服务器

如何将字符串argv[]赋给C中的整型数组?

ARM64 ASIMD固有的加载uint8_t* 到uint16x8(x3)?

在C++中使用函数指针的正确语法

Clang警告称,`ffi_type`与`sizeof`不兼容

如何使用C++在控制台中以彩色打印被阻止的客户端

在进程之间重定向输出和输入流的问题

';\n&39;和';\r&39;中的';\n&39;之间有什么关系?

使用%f格式说明符打印整数值

int * 指向int的哪个字节?

不带Malloc的链表

从整型转换为浮点型可能会改变其值.

`%%的sscanf无法按预期工作

If语句默认为true

使用 GCC 将一个函数中初始化的 struct 体实例通过指针传递到 C 中的另一个函数会产生不同的结果

子进程不会修改父进程中的统计信息

创建 makefile 来编译位于不同目录中的多个源文件