为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这个C ++片段编译(非void函数不返回值)

为什么这个C ++片段编译(非void函数不返回值)

C++
摇曳的蔷薇 2019-08-08 16:25:46
为什么这个C ++片段编译(非void函数不返回值)今天早上我在我的一个图书馆找到了这个:static tvec4 Min(const tvec4& a, const tvec4& b, tvec4& out){     tvec3::Min(a,b,out);     out.w = min(a.w,b.w);}我期望编译器错误,因为此方法不返回任何内容,并且返回类型不返回void。想到的唯一两件事是在调用此方法的唯一位置,不使用或存储返回值。(此方法应该是void- tvec4返回类型是复制和粘贴错误)tvec4正在创建一个默认构造,这看起来有点不同,哦,C ++中的其他所有东西。我还没有找到解决这个问题的C ++规范部分。参考文献(ha)表示赞赏。更新在某些情况下,这会在VS2012中生成错误。我没有缩小具体细节,但它仍然很有趣。
查看完整描述

3 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

这是来自C ++ 11草案标准部分未定义行为。返回声明2段说:6.6.3

[...]离开函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为。[...]

这意味着编译器没有义务提供错误或警告,因为在所有情况下都很难诊断。我们可以从草案标准草案中未定义行为的定义中看出这一点,1.3.24其中说:

[...]允许的未定义行为包括完全忽略不完全结果的情况,在翻译或程序执行期间以环境特征(有或没有发出诊断消息)的文件化方式行事,终止翻译或执行(发布诊断信息)。[...]

虽然在这种情况下我们可以获得两者gccclang使用-Wall标志生成一个wanring ,这给了我类似的警告:

警告:控制到达非空函数的末尾[-Wreturn-type]

我们可以使用-Werror=return-type标志将此特定警告转换为错误。我也喜欢用-Wextra -Wconversion -pedantic我自己的个人项目。

正如ComicSansMS在Visual Studio中提到的,这段代码会生成C4716,默认情况下是一个错误,我看到的消息是:

错误C4716:'Min':必须返回一个值

并且在并非所有代码路径都返回值的情况下,它将生成C4715,这是一个警告。


查看完整回答
反对 回复 2019-08-08
?
噜噜哒

TA贡献1784条经验 获得超7个赞

也许在一些阐述为什么这个问题的一部分:

事实证明,对于C ++编译器来说,确定函数是否在没有返回值的情况下退出是非常困难的。除了以显式返回语句结尾的代码路径以及从函数末尾开始的代码路径之外,还必须考虑longjmp函数本身及其所有被调用者中的潜在异常抛出或s。

虽然编译器很容易识别看起来可能缺少返回的函数,但要证明它缺少返回却相当困难。为了解除编译器供应商的这种负担,标准不要求它产生错误。

因此,编译器供应商可以自由地生成警告,如果他们非常确定函数缺少返回,那么用户可以在编译器实际上错误的极少数情况下自由地忽略/屏蔽该警告。


查看完整回答
反对 回复 2019-08-08
?
慕少森

TA贡献2019条经验 获得超9个赞

使用-Wreturn-type选项编译代码:

$ g++ -Wreturn-type source.cpp

这会给你警告。如果您也使用警告,则可以将警告变为错误-Werror

$ g++ -Wreturn-type -Werror source.cpp

请注意,这会将所有警告变为错误。因此,如果你想要特定警告的错误,比如说-Wreturn-type,只需键入return-type不带-W部分:

$ g++ -Werror=return-type source.cpp

通常,您应该始终使用-Wall包含最常见警告的选项 - 这也包括缺少return语句。除此之外-Wall,您还可以使用-Wextra,其中包括未包含的其他警告-Wall


查看完整回答
反对 回复 2019-08-08
  • 3 回答
  • 0 关注
  • 654 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信