首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么为不返回任何内容的函数声明返回值只会导致gcc8中的运行时崩溃。

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

Stack Overflow用户
提问于 2019-09-18 12:10:32
回答 1查看 222关注 0票数 3

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

具体问题:

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

main.cpp:

代码语言:javascript
复制
#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;
}

运行时崩溃:

代码语言:javascript
复制
g++-8 -O2  -o main main.cpp
./main
Hello World!
Hello World!
Segmentation fault (core dumped)

与以下方面合作:

代码语言:javascript
复制
g++-7 -O2  -o main main.cpp

代码语言:javascript
复制
g++-8 -o main main.cpp

编辑:问题在C++中省略返回语句回答了我的第二个问题,但不是第一个问题(关于gcc 7和gcc 8的区别)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-18 12:52:43

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

比较见编译器资源管理器中的原始代码

代码语言:javascript
复制
<...>
setYear(int):
        mov     DWORD PTR year[rip], edi
.LC0:
        .string "Hello World!"
main:
<...>

返回类型int的代码已更改为void (链接):

代码语言:javascript
复制
<...>
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不同)。这是非常罕见的,当你想要避免这个选项,它是非常有用的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57992494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档