gpt4 book ai didi

c++ - 为什么为一个什么都不返回的函数声明一个返回值只会导致 gcc8 中的运行时崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 00:50:16 27 4
gpt4 key购买 nike

在下面的代码中,函数声明/定义为 int setYear(int year_h){year = year_h;}(而不是 void setYear(...) ,导致 gcc 8 中的运行时崩溃并且仅使用标志 -O[X]

具体问题:

  1. gcc 8 在 gcc 7 中有哪些变化?
  2. 我可以使用哪些标志(如果有的话)在 gcc8 中生成编译错误(而不是警告)?

主要.cpp:

#include <iostream>

using namespace std;

int year = 2000;
int setYear(int year_h){year = year_h;}

int main()
{
cout << "Hello World!" << endl;
setYear(2019);
cout << "Year: " << year << endl;
return 0;
}

运行时崩溃:

g++-8 -O2  -o main main.cpp
./main
Hello World!
Hello World!
Segmentation fault (core dumped)

适用于:

g++-7 -O2  -o main main.cpp

g++-8 -o main main.cpp

编辑:问题 Omitting return statement in C++回答我的第二个问题,但不是第一个问题(关于 gcc 7 和 gcc 8 之间的区别)。

最佳答案

从 GCC 8 开始,当您的源代码使用 -Og 编译时,您的 setYear 函数根本没有 RET 指令(在更高级别的函数是内联的,这使得理解正在发生的事情变得更加困难),并且调用该函数的 main 也没有任何延续。

查看比较 the original code at Compiler Explorer :

<...>
setYear(int):
mov DWORD PTR year[rip], edi
.LC0:
.string "Hello World!"
main:
<...>

并将返回类型 int 更改为 void ( link ) 的代码:

<...>
setYear(int):
mov DWORD PTR year[rip], edi
ret
.LC0:
.string "Hello World!"
.LC1:
.string "Year: "
main:
<...>

仅此遗漏就足以让执行流撞到 main(.string 在另一部分中声明),再次执行它而不是返回到点电话。显然,当 main 返回非 以外的函数中没有 return 语句时,gcc 认为不值得添加 RET 指令>无效

当然,在很多情况下,编译器在编译阶段很容易检测到问题。我建议使用 -Werror=return-type 选项,这会无条件地导致错误(与一般的 -Werror 不同)。当您想要避免使用此选项时,这种情况非常罕见,而且它非常有用。

关于c++ - 为什么为一个什么都不返回的函数声明一个返回值只会导致 gcc8 中的运行时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57992494/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com