C++ C+;是否必须使用返回语句+;不返回void的函数? 而不使用返回< /C> >语句——在这种情况下行为完全被定义。
我使用gcc(MinGW)并设置了-pedantic标志。是的,它必须返回一个值 从函数末尾流出是一个错误 相当于没有价值的回报; 这将导致在中出现未定义的行为 值返回函数C++ C+;是否必须使用返回语句+;不返回void的函数? 而不使用返回< /C> >语句——在这种情况下行为完全被定义。,c++,C++,我使用gcc(MinGW)并设置了-pedantic标志。是的,它必须返回一个值 从函数末尾流出是一个错误 相当于没有价值的回报; 这将导致在中出现未定义的行为 值返回函数 将为主题带来更多的光这是强制性的吗?我不这么认为,但是,在我的C++标准(除了Meor,返回0)的理解中,没有返回一个无空返回函数的值。 这是不是意味着没事?可能不是-如果函数应该返回一个值,那么您应该返回一个值,这在复杂的代码库中可能会变得非常混乱。§6.6.3/2: 从函数末尾流出相当于没有值的返回;这会导致值返回函数中
将为主题带来更多的光这是强制性的吗?我不这么认为,但是,在我的C++标准(除了Meor,返回0)的理解中,没有返回一个无空返回函数的值。 这是不是意味着没事?可能不是-如果函数应该返回一个值,那么您应该返回一个值,这在复杂的代码库中可能会变得非常混乱。§6.6.3/2: 从函数末尾流出相当于没有值的返回;这会导致值返回函数中出现未定义的行为 所以这取决于你对强制性的定义。你一定要吗?不。但是如果您希望您的程序具有定义良好的行为,可以* *
main
是一个例外,请参见§3.6.1/5。如果控件到达main
的末尾时没有返回return
,它将具有返回0的效果代码>它是强制性的——当此类函数结束时没有返回任何内容时,这是一种未定义的行为(因此编译器实际上可能实现某种特殊行为)。然而,也有一些特殊情况
::main
是一个异常,假设返回0代码>位于其代码的末尾
此外,您不必在返回不干净的函数中返回值,例如:
int Foo() {
throw 42;
}
函数中的return语句声明为returningnonvoid并不是必须的,也不必导致未定义的行为
这种职能可以:
- 不返回,比如进入无限循环
- 通过抛出异常返回
- 调用本身不返回的函数,例如
std::terminate
当然,如果函数总是通过执行上述操作之一来避免未定义的行为,那么如果可能的话,它可能不应该被声明为返回非void
一个明显的情况是,如果它是一个虚拟函数,对于类层次结构中的某个特定点,它不能返回有效值,并且总是通过异常退出。忘记在值返回函数的某个控制路径中包含return
语句不会使代码格式错误。也就是说,您通常应该期望代码能够编译(可能带有警告)。从这个意义上说,它不是“强制性的”
但是,C++中的值返回函数的结束实际上是不确定的行为。(在C语言中,只有当调用代码实际使用结果时,它才是未定义的行为。)正如GMan所说,唯一的例外是main函数。我仍然看到大量的书返回0,这并不是真的需要。哦,我想情况可能更糟,你可以从一本使用void main()而不是int main()的书中学习。
但是我认为你应该从这些中学到的是,你的编译器抱怨是有原因的,你应该注意到这一点,因为从长远来看,这通常会让你头疼。我听说Herb Schildt的书不好。是的,这是强制性的。另外,考虑买一本更好的书。Schildt的大多数书通常被认为是不好的。这就是为什么我用-Werror
编译…相关:显然-Werror在这里不是一个解决方案。未定义的行为远比崩溃更糟糕。@Jurily:我同意,但我不明白这与这里的任何事情有什么关系。注意措辞:它适用于执行,而不是编译。如果您输入的函数的返回类型不是void
,并且没有结束,则不需要使用返回来避免未定义的行为。@july,真的吗?未定义的行为可能意味着它决定格式化你的硬盘,向你的老板发送儿童色情信息,并在电子邮件中抄送FBI。未定义的行为意味着它可以在那之后做任何事情,包括,甚至超过成为一个彻头彻尾的混蛋。你最好不要到一个已知的状态。至少如果它崩溃了,我知道它已经停止做坏事了。例外的例子可能就是为什么这只是一个警告。编译器不太善于知道实际使用了哪些控制路径,错误会导致许多非常好的代码被拒绝。@DennisZickefoose-这“只是一个警告”,因为从函数结束处返回的行为会产生未定义的行为(除了main()
)。当行为未定义时,不需要诊断(尽管编译器可能会选择发出警告-这是实现质量问题,而不是标准的要求)。无论如何,还有很多其他情况下编译器无法可靠地选择哪些控制路径被使用或未被使用。非常感谢。我现在把它看作是哲学上的细节。通过“必须”,标准意味着“必须或未知的行为将发生。”C++标准允许控件离开<代码>主体()/代码>而不使用<代码>返回< /C> >语句——在这种情况下行为完全被定义。