![](/img/trans.png)
[英]Difference between gcc5 and gcc8 with respect to return values of a function
[英]Why declaring a return value for a function that doesn't return nothing leads to run-time crash in gcc8 only
在下面的代码中,将一个函数声明/定义为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的区别)。
从GCC 8开始,当使用-Og
编译源代码时, setYear
函数根本没有RET
指令(在更高级别上,该函数被内联,这使得了解正在发生的事情更加困难),并且该函数的main
调用位置也缺乏任何延续。
在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
返回non- void
之外没有return
语句时,gcc认为不值得添加RET
指令。
当然,在许多情况下,编译器可以在编译阶段轻松检测到该问题。 我建议使用-Werror=return-type
选项,该选项无条件地使其成为错误(与-Werror
通常不同)。 当您要避免使用此选项时,这种情况非常罕见,它非常有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.