如果函数没有返回任何值,并且返回types有效,编译器是否可以扔垃圾?
如果一个函数的返回types不是void
,并且函数没有返回任何东西,那么我猜编译器会返回一个垃圾值(可能被看作未初始化的值)。 它发生在编译时,为什么不能抛出一个错误?
例如,
int func1() { return; // error } int func2() { // does not return anything }
第二个func2
应该会抛出一个错误,但是不会。 是有原因的吗? 我的想法是,它可以被看作是一个未初始化的值,所以如果我们需要在第二种情况下抛出错误,那么我们需要抛出错误,如果一个值未初始化,说
int i; // error int i = 6; // okay
任何想法,或者这是一个重复的问题? 我感谢您的帮助。
在C ++中,这样的代码具有未定义的行为:
[stmt.return] / 2 …从一个函数的结尾stream出相当于一个没有值的返回; 这会导致值返回函数中的未定义行为。 …
大多数编译器会产生类似于问题中的代码的警告。
C ++标准并不要求这是一个编译时错误,因为在一般情况下,要正确地确定代码是否实际运行在函数的末尾,或者如果函数通过exception退出(或longjmp或类似的机制)。
考虑
int func3() { func4(); }
如果func4()
抛出,那么这个代码是完全正确的。 编译器可能无法看到func4()
的定义(因为单独编译),所以不知道它是否会抛出。
此外,即使编译器可以certificatefunc4()
不会抛出,但它仍然必须certificatefunc3()
实际上在被合法地拒绝之前被调用。 这样的分析需要检查整个程序,这与单独的编译不相容,在一般情况下甚至是不可能的。
在C中,引用N1256 6.9.1p12:
如果到达终止函数的} ,并且调用者使用该函数调用的值,则行为是不确定的。
因此,非void函数无法返回值是合法的(但是一个坏主意),但是如果这样做并且调用者试图使用结果,则行为是未定义的。 请注意,它不一定只返回一些任意值; 就标准而言,任何事情都是可能的。
之前的ANSI C没有void
关键字,所以编写一个没有返回值的函数的方法是省略返回types,使其隐式返回int
。 在return
值函数中要求return
语句会破坏旧代码。 它也需要编译器进行额外的分析,以确定所有的代码path都是return
语句; 这样的分析对于现代编译器来说是合理的,但是当C首次被标准化时,可能是一个过度的负担。
C ++稍微严格些。 在C ++中:
从函数的结尾stream出相当于没有值的返回 ; 这会导致值返回函数中的未定义行为。
因此,调用者是否尝试使用(不存在的)结果的行为是不确定的。
C和C ++编译器当然可以警告丢失的return
语句,或者关于不执行return
语句的函数末尾的控制path,但是相应的标准不要求它们这样做。
在C中, 只要调用代码不尝试使用返回值 ,那么对于非void函数完成而不返回值实际上是合法的。
另一方面,没有expression式的return
语句不允许出现在非void函数中。
对于第一种情况,C99标准的相关部分是§6.9.1:
如果到达终止函数的
}
,并且调用者使用该函数调用的值,则行为是不确定的。
第二种情况是§6.8.6.4:
没有expression式的
return
语句只能出现在返回types为void
的函数中。
你的两个function都不健全。 它们之间的区别是你的func1
违反了关于如何使用return
语句的规则,而你的func2
是未定义的行为。 你func1
的return
语句是非法的,一个实现必须诊断这个。 func2
缺lessreturn语句是未定义的行为。 大多数编译器会诊断这个,但是没有必要。