C函数的隐式int返回值

时间:2012-04-09 20:05:49

标签: c function legacy-code

我用Google搜索,似乎无法找到这个简单问题的答案。

使用遗留代码库(最近移植到Linux,并慢慢更新到新编译器),我看到了很多

int myfunction(...)
{
// no return...
}

我知道函数的隐式返回TYPE是int,但是当没有指定返回时,隐式返回VALUE是什么。我已经测试过并且得到了0,但这只是用gcc。这个编译器是特定的还是标准定义为0?

编辑:12/2017 调整接受的答案,基于它引用更新版本的标准。

7 个答案:

答案 0 :(得分:21)

从新约中引用的'89标准:

  

离开函数末尾相当于没有表达式的返回。在任何一种情况下,返回值都是未定义的。

该标准通常表达预先存在的实施的实地行为。

答案 1 :(得分:10)

这只是未定义的行为;如果你没有填充返回区域(例如通常为eax/rax on x86 family processors),它将通过你的函数中的一些副作用设置最后设置的值。

请参阅Is a return statement mandatory for C++ functions that do not return void?,这基本上与此问题重复(除了标记为C ++)。

答案 2 :(得分:9)

这样的事情是可能的,但只能假设从不使用函数的返回值。 C11标准在第6.9.1段中说明:

  

如果到达终止函数的},则为   函数调用由调用者使用,行为未定义。

(AFAIR标准的先前版本有类似的措辞)

因此,将所有类型的函数转换为void函数是个好主意,因此不能诱使这样的函数用户使用返回值。

答案 3 :(得分:8)

即使函数返回类型不是void,函数末尾也不会强制返回return语句。不需要诊断,也不是未定义的行为。

示例(已定义的行为):

int foo(void)
{
}

int main()
{
    foo();
}

但是读取foo的返回值是未定义的行为:

int bla = foo();  // undefined behavior

来自C标准:

  

(C99,6.9.1p12)“如果达到了终止函数的},并且调用者使用了函数调用的值,则行为是未定义的。”

main函数是此规则的一个例外,就像在}中达到main一样,它就像有一个return 0;语句一样。

答案 4 :(得分:2)

如果return语句始终不返回值,则该函数最好转换为并声明为返回void

void myfunction(...)
{
    ...
    return;
    ...
}

如果函数中有一些return expr;和一些return;语句,那么你需要决定哪个是更好的行为,并使它们保持一致 - 要么总是返回一个值并保留类型如int或永不返回值并将类型更改为void

请注意,您需要声明已修改的函数以返回void(在标题中,除非它们是 - 或应该是 - static并隐藏在单个源文件中),因为默认返回int的类型(假定返回类型)不再有效。

答案 5 :(得分:1)

在该函数中它可能总是为零,但在大多数体系结构(当然是x86)上,return语句将特定寄存器的内容移动到堆栈上的特定位置,调用者将检索该位置并将其用作其返回函数。

return语句会将传递给它的变量放在该位置,这样它就会是一个不同的值。我没有放置特定的返回声明的经验是它相当随机的返回,你不能依赖它是同样的事情。

答案 6 :(得分:0)

我确定对于返回类型不是void的函数来说,它是未定义的行为,以省略return语句。在C99中,main有一个例外,如果省略return语句,则假定它隐式返回0,但这不适用于任何其他函数。

它可能适用于特定的平台/编译器组合,但您不应该依赖这些细节。在代码中使用任何类型的未定义行为都会使其无法移植。通常在遗留代码中看到未定义的行为。