how*_*rks 14 c c++ initialization return-value garbage
如果函数的返回类型不是void
,并且函数没有返回任何内容,那么我猜编译器会返回一个垃圾值(可能被视为未初始化的值).它发生在编译时,为什么不应该抛出错误呢?
例如,
int func1() {
return; // error
}
int func2() {
// does not return anything
}
Run Code Online (Sandbox Code Playgroud)
第二个func2
应该抛出错误,但事实并非如此.有原因吗?我的想法是,它可以看作是一个未初始化的值,所以如果我们需要在第二种情况下抛出错误,那么我们需要抛出错误,如果一个值是未初始化的,比如说
int i; // error
int i = 6; // okay
Run Code Online (Sandbox Code Playgroud)
有什么想法,或者这是一个重复的问题?我感谢您的帮助.
Man*_*rse 17
在C++中,此类代码具有未定义的行为:
[stmt.return]/2 ...从函数末尾流出相当于没有值的返回值; 这会导致值返回函数中的未定义行为....
大多数编译器都会针对与问题类似的代码生成警告.
C++标准并不要求这是一个编译时错误,因为在一般情况下,很难正确地确定代码是否实际在函数末尾运行,或者函数是否通过异常退出(或者是一个longjmp)或类似的机制).
考虑
int func3() {
func4();
}
Run Code Online (Sandbox Code Playgroud)
如果func4()
抛出,那么这段代码完全没问题.编译器可能无法看到func4()
(由于单独的编译)的定义,因此无法知道它是否会抛出.
此外,即使编译器可以证明func4()
不抛出,它仍然必须证明func3()
在它合法地拒绝该程序之前实际被调用.这种分析需要检查整个程序,这与单独的编译不兼容,并且在一般情况下甚至是不可能的.
Kei*_*son 10
在C中,引用N1256 6.9.1p12:
如果到达终止函数的},并且调用者使用函数调用的值,则行为是未定义的.
因此,非void函数无法返回值是合法的(但是一个坏主意),但如果它这样做并且调用者尝试使用结果,则行为是未定义的.注意,它不一定只返回一些任意值; 就标准而言,一切皆有可能.
前ANSI C没有void
关键字,所以编写一个没有返回值的函数的方法是省略返回类型,使其隐式返回int
.return
在值返回函数中需要语句会破坏旧代码.它还需要编译器进行额外的分析,以确定所有代码路径都符合return
语句; 这样的分析对于现代编译器来说是合理的,但是当C首次标准化时,这可能是一个过度的负担.
C++稍微严格一些.在C++中:
流出函数末尾相当于没有值的返回 ; 这会导致值返回函数中的未定义行为.
因此,无论调用者是否尝试使用(不存在)结果,行为都是未定义的.
C和C++编译器当然可以警告缺少return
语句,或关于在不执行return
语句的情况下从函数末尾掉下来的控制路径,但各自的标准并不要求它们这样做.
在 C 中,只要调用代码不尝试使用返回值,非 void 函数完成而不返回值实际上是合法的。
另一方面,return
没有表达式的语句不允许出现在非空函数中。
C99标准的相关部分是第一种情况的§6.9.1:
如果
}
到达终止函数的 ,并且调用者使用了函数调用的值,则行为未定义。
和 §6.8.6.4 对于第二种情况:
return
没有表达式的语句只能出现在返回类型为 的函数中void
。