繁体   English   中英

为什么声明不返回任何内容的函数的返回值只会导致gcc8中的运行时崩溃

[英]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]

具体问题:

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

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的代码已更改为voidlink ):

<...>
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.

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