如果函数没有返回任何值,并且返回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是未定义的行为。 你func1return语句是非法的,一个实现必须诊断这个。 func2缺lessreturn语句是未定义的行为。 大多数编译器会诊断这个,但是没有必要。