我有一些遗留的C代码,我在Linux上用gcc版本4.9.2编译,在[-Wreturn-type]上有返回类型警告。我有如下功能:
int somefn() {
// .. do something ..
// no explicit return statement
}
,来电者接到以下电话:
if (somefn()){
// handling of success
}
else {
// handling of failure
}
当警告被抑制时,编译+链接一切正常,在运行时,我们可能会有惊喜,可能出现什么问题?
答案 0 :(得分:1)
我在Linux上使用gcc版本4.9.2编译,并在[-Wreturn-type]
上发出了返回类型警告
调用者期望成功为真(在C中,解释为非零),对于失败则为0。这就是发生的事情。由于返回非void的函数在调用时会在堆栈上为返回值创建空间,然后上下文切换到被调用者,最后,当控件返回调用者时,上下文切换回弹出所有本地来自堆栈的变量,并将返回值保存在堆栈中,以便在从被调用者返回后由调用者弹出。因此,没有明确的return语句会导致返回一些值。这相当于将显式返回语句设为'return 1;'或'return 0;'作为适当的。因此,更好(当然)是有明确的退货声明,例如
int somefn() {
// .. do something ..
if (..somecond..)
return 0; // failure
else
return 1; // success
}
为避免出现意外,我会说,编译器应将'no return statement in function returning non-void'
标记为错误。
答案 1 :(得分:1)
引用C11
,章节§6.9.1,函数定义,语义
如果到达了终止函数的
}
,则使用函数调用的值 调用者,行为未定义。
因此,该标准指定了函数定义的语义,它明确指出(对于非void函数返回类型)一个函数,该函数在没有return语句的情况下终止,并且返回的值在调用者中使用{{3} }。
因此,它接受语法编写函数本身是可能的,但尝试使用它将是UB。它没有将此声明为约束违规,我认为没有理由让符合标准的编译器产生“错误”。
如果您需要严格检查(顺便推荐),请使用-Werror
选项。