3Da*_*ave 128 c++ methods c++11 visual-studio-2012
今天早上我在我的一个图书馆找到了这个:
static tvec4 Min(const tvec4& a, const tvec4& b, tvec4& out)
{
tvec3::Min(a,b,out);
out.w = min(a.w,b.w);
}
Run Code Online (Sandbox Code Playgroud)
我期望编译器错误,因为此方法不返回任何内容,并且返回类型不返回void.
想到的唯一两件事是
在调用此方法的唯一位置,不使用或存储返回值.(此方法应该是void- tvec4返回类型是复制和粘贴错误)
tvec4正在创建一个默认构造,这看起来有点不同,哦,C++中的其他所有东西.
我还没有找到解决这个问题的C++规范部分.参考文献(ha)表示赞赏.
更新
在某些情况下,这会在VS2012中生成错误.我没有缩小具体细节,但它仍然很有趣.
Sha*_*our 153
这是来自C++ 11草案标准部分的未定义行为.返回声明第2段说:6.6.3
[...]离开函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为.[...]
这意味着编译器没有义务提供错误或警告,因为在所有情况下都很难诊断.我们可以从草案标准草案中未定义行为的定义中看出这一点,1.3.24其中说:
[...]允许的未定义行为包括完全忽略不完全结果的情况,在翻译或程序执行期间以环境特征(有或没有发出诊断消息)的文件化方式行事,终止翻译或执行(发布诊断信息).[...]
虽然在这种情况下我们可以获得两者gcc并clang使用-Wall标志生成一个wanring ,这给了我类似的警告:
警告:控制到达非空函数的末尾[-Wreturn-type]
我们可以使用-Werror=return-type标志将此特定警告转换为错误.我也喜欢用-Wextra -Wconversion -pedantic我自己的个人项目.
正如ComicSansMS在Visual Studio中提到的,这段代码会生成C4716,默认情况下是一个错误,我看到的消息是:
错误C4716:'Min':必须返回一个值
并且在并非所有代码路径都返回值的情况下,它将生成C4715,这是一个警告.
Com*_*sMS 58
也许在一些阐述为什么这个问题的一部分:
事实证明,对于C++编译器来说,确定函数是否在没有返回值的情况下退出是非常困难的.除了以显式返回语句结尾的代码路径以及从函数末尾开始的代码路径之外,还必须考虑longjmp函数本身及其所有被调用者中的潜在异常抛出或s.
虽然编译器很容易识别看起来可能缺少返回的函数,但要证明它缺少返回却相当困难.为了解除编译器供应商的这种负担,标准不要求它产生错误.
所以编译器厂商可以自由地产生一个警告,如果他们是相当肯定的功能缺少回报,用户就可以自由地忽略/掩盖在极个别情况下,编译器实际上是错误的警告.
†:在一般情况下,这相当于暂停问题,因此机器实际上不可能可靠地决定这一点.
Naw*_*waz 22
使用-Wreturn-type选项编译代码:
$ g++ -Wreturn-type source.cpp
Run Code Online (Sandbox Code Playgroud)
这会给你警告.如果您也使用警告,则可以将警告变为错误-Werror:
$ g++ -Wreturn-type -Werror source.cpp
Run Code Online (Sandbox Code Playgroud)
请注意,这会将所有警告变为错误.因此,如果你想要特定警告的错误,比如说-Wreturn-type,只需键入return-type不带-W部分:
$ g++ -Werror=return-type source.cpp
Run Code Online (Sandbox Code Playgroud)
通常,您应该始终使用-Wall包含最常见警告的选项 - 这也包括缺少return语句.除此之外-Wall,您还可以使用-Wextra,其中包括未包含的其他警告-Wall.
Jir*_*ika 21
也许在一些额外的阐述为什么这个问题的一部分.
C++的设计使得大量预先存在的C代码体以最小的更改量进行编译.不幸的是,C本身对最早的预标准C付出了类似的责任,它甚至没有void关键字,而是依赖于默认的返回类型int.C函数通常会返回值,并且只要表面上与Algol/Pascal/Basic程序类似的代码没有任何return语句,该函数就会在引擎盖下返回堆栈中剩余的垃圾.调用者和被调用者都不能以可靠的方式分配垃圾的值.如果每个调用者都忽略了垃圾,那么一切都很好,C++继承了编译这些代码的道德义务.
(如果调用者使用返回的值,则代码可能表现不确定,类似于处理未初始化的变量.编译器是否可以通过C的假设后继语言可靠地识别差异?这几乎是不可能的.调用者和被调用者可能在不同的编译单元中.)
隐含int只是这里涉及的C遗产的一部分.根据参数,"调度程序"函数可能会从某些代码分支返回各种类型,并且不会从其他代码分支返回任何有用的值.通常会声明这样的函数返回一个足够长的类型来保存任何可能的类型,并且调用者可能需要将其强制转换或从中提取union.
因此,最深层次的原因可能是C语言创建者认为,不返回任何值的过程只是一个不重要的特殊功能案例; 由于缺乏对最古老的C方言中函数调用的类型安全性的关注,这个问题变得更加严重.
虽然C++确实破坏了与C(示例)的一些最糟糕方面的兼容性,但是编译没有值的return语句(或函数末尾的隐式无值返回)的意愿不是其中之一.
Zac*_*and 12
如前所述,这是未定义的行为,并将为您提供编译器警告.我工作过的大多数地方都要求你打开编译器设置将警告视为错误 - 这会强制所有代码必须编译为0错误和0警告.这是一个很好的例子,说明为什么这是一个好主意.
| 归档时间: |
|
| 查看次数: |
13860 次 |
| 最近记录: |