在下面的代码中,函数声明/定义为int setYear(int year_h){year = year_h;} (而不是void setYear(...),导致gcc 8中的运行时崩溃,并且只使用标志-O[X] )。
具体问题:
main.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编辑:问题在C++中省略返回语句回答了我的第二个问题,但不是第一个问题(关于gcc 7和gcc 8的区别)。
发布于 2019-09-18 12:52:43
从GCC 8开始,您的setYear函数在用-Og编译源代码时根本没有RET指令(在更高的级别上,函数是内联的,使得更难理解正在发生的事情),调用函数的main也缺少任何延续。
<...>
setYear(int):
mov DWORD PTR year[rip], edi
.LC0:
.string "Hello World!"
main:
<...>返回类型int的代码已更改为void (链接):
<...>
setYear(int):
mov DWORD PTR year[rip], edi
ret
.LC0:
.string "Hello World!"
.LC1:
.string "Year: "
main:
<...>仅这一遗漏就足以使执行流碰到main (.string在另一节中声明),再次执行它,而不是返回到调用点。显然,gcc认为,除了返回非- RET的函数中没有return语句时,添加main指令是不值得的。
当然,在许多情况下,编译器在编译阶段很容易发现问题。我建议无条件地使用-Werror=return-type选项,这会使这成为一个错误(与一般的-Werror不同)。这是非常罕见的,当你想要避免这个选项,它是非常有用的。
https://stackoverflow.com/questions/57992494
复制相似问题