C中的隐式返回值,在应该返回非void的函数中没有显式返回

时间:2017-05-24 11:13:41

标签: c compiler-warnings gcc4.9

我有一些遗留的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
}

当警告被抑制时,编译+链接一切正常,在运行时,我们可能会有惊喜,可能出现什么问题?

2 个答案:

答案 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选项。

相关问题