当一个具有警告"控制到达非空函数结束"的函数被调用时,实际发生了什么?

Kir*_*rov 12 c c++

我知道这个消息意味着什么,我只是想知道为什么它不是错误消息,而只是一个警告?

在这种情况下会发生什么?例如,假设我有一个功能

int f()
{
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时会发生什么?在这种情况下
,编译器是否添加"非初始化"的返回int
或者丢失的返回可能导致堆栈损坏?
或者(绝对)未定义的行为

用gcc 4.1.2和4.4.3测试


编辑:阅读答案我理解一件事,阅读评论 - 另一个..

好吧,让我们总结一下:它是未定义的行为.那么,这意味着可能导致堆栈损坏,对吧?(甚至意味着,我的电脑可能会开始通过麦克风插孔把腐烂的西红柿扔到我身上,尖叫着 - "你做了什么?").

但如果是这样,那么为什么这里的最佳答案说,堆栈损坏不会发生,同时,行为是未定义的?

并且未定义?调用者,尝试使用"未返回的值",或只是函数的结尾是未定义的,如果它必须返回值,但它不是?

或者它不是未定义的行为,只是试图使用该值的用户(未返回,噢!)将"接收"未定义的?换句话说 - 只是一些垃圾价值,没有更多的事情可以发生?

pau*_*sm4 11

答:不,缺少的回报不会导致堆栈损坏

答:是的,如果调用者试图读取和/或使用(未定义的!)返回值,则行为将是"未定义的".

PS:

这是C++的引用:

C++03§6.6.3/ 2:

流出函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为.

  • 说未定义的行为与您声称它不会导致堆栈损坏的说法不一致.在某些实现*(可能甚至是所有现有的实现)中,它可能不会这样做,但"未定义的行为"意味着,就标准而言,*任何*都可能发生 - 包括堆栈损坏. (6认同)
  • @Dirk:大多数编译器为没有任何名为`eax`的系统生成代码. (2认同)

Kei*_*son 7

你问过C和C++.这两种语言的规则不同.

在C中,仅当调用者尝试使用函数返回的值时,行为才是未定义的.如果你有:

int func(void) {
    /* no return statement */
}

...

func();
Run Code Online (Sandbox Code Playgroud)

然后行为很明确.

在C++中,行为是未定义的(如果函数被调用)是否调用者是否尝试使用结果.(这是出于历史原因;前ANSI C没有void关键字,并且通常无法定义(隐式)返回值的函数int.)

John Bode的回答已经引用了2011年ISO C标准的N1570草案,6.9.1p12:

如果到达终止函数的},并且调用者使用函数调用的值,则行为是未定义的.

paulsm4引用了C++标准; 引用最新的2011版本,6.6.3p2:

流出函数的末尾相当于return没有值; 这会导致值返回函数中的未定义行为.

导致C允许值返回函数无法返回值的历史原因,只要调用者未使用该值,就不适用于C++,其设计不受需要避免的强烈影响打破旧的(ANSI C之前的)代码.

在C(从C99开始)和C++中,main函数是一个特例; 在没有执行返回}main情况下达到结束相当于a return 0;.(C允许main返回除了以外的实现定义类型int;在该(罕见)情况下,从结尾处掉落会向主机环境返回未指定的终止状态.)

当然,return从值返回函数中省略该语句,或者有一条未达到return语句的可能执行路径,这是一个坏主意.它只有在古代遗留的C代码中才有意义,它可以int作为替代品使用void,并且在main(尽管main我个人喜欢明确地使用return 0;).