我用Google搜索,似乎无法找到这个简单问题的答案。
使用遗留代码库(最近移植到Linux,并慢慢更新到新编译器),我看到了很多
int myfunction(...)
{
// no return...
}
我知道函数的隐式返回TYPE是int,但是当没有指定返回时,隐式返回VALUE是什么。我已经测试过并且得到了0,但这只是用gcc。这个编译器是特定的还是标准定义为0?
编辑:12/2017 调整接受的答案,基于它引用更新版本的标准。
答案 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,但这不适用于任何其他函数。
它可能适用于特定的平台/编译器组合,但您不应该依赖这些细节。在代码中使用任何类型的未定义行为都会使其无法移植。通常在遗留代码中看到未定义的行为。