C++ 将双精度降级为浮动时没有警告

C++ 将双精度降级为浮动时没有警告,c++,macos,g++,double,C++,Macos,G++,Double,当我在带有OSX 10.8和g++4.2.1的Mac 64位机器上编译以下代码时,不会生成任何警告 #include "stdio.h" int main() { double d= 3.14159; float res= d; printf("%f\n", res); return 0; } 显然,自动将double降级为float可能非常危险,但编译器不会生成任何警告。我能找到的唯一解决方案是使用标志-Wshorten-64-to-32 在我看来,这是一个

当我在带有OSX 10.8和g++4.2.1的Mac 64位机器上编译以下代码时,不会生成任何警告

#include "stdio.h"

int main()
{
    double d= 3.14159;
    float res= d;
    printf("%f\n", res);
    return 0;
}
显然,自动将double降级为float可能非常危险,但编译器不会生成任何警告。我能找到的唯一解决方案是使用标志-Wshorten-64-to-32

在我看来,这是一个如此明显的错误,令我惊讶的是,编译器在默认情况下没有捕捉到这个错误。是否有任何原因导致g++在默认情况下无法捕获此错误?有没有更好的方法可以在不使用-Wshorten-64-to-32的情况下生成警告

如果您想知道,-Wall也不会生成警告


提前感谢您的帮助。

行为符合以下标准:

4.8浮点转换[conv.double]

浮点类型的prvalue可以转换为另一种浮点类型的prvalue。如果 源值可以精确地表示在目标类型中,转换的结果就是这样 代表性。如果源值介于两个相邻的目标值之间,则转换的结果 是实现定义的对这些值的选择。否则,行为是未定义的

此外,浮点类型的值可以转换为整数类型的值:

4.9浮点积分转换[conv.fpint]

浮点类型的prvalue可以转换为整数类型的prvalue。转换截断; 也就是说,小数部分被丢弃。如果无法删除截断的值,则行为未定义 在目标类型中表示


虽然这是真的,但它并没有讨论为什么g++在默认情况下不更具警告性。(当然,我认为这个问题没有一个好的答案。)@user2864740同意,答案并没有涉及到G++的警告策略。但这也并非完全无关。不确定,也许我应该删除它:)。不,我认为它很好(我也投了赞成票)-有这样的信息是很好的。我只想指出,我相信OP是在寻找更多的g++/具体实现的理由。谢谢你的回答!真正的问题似乎是“为什么GNU/g++在默认情况下不应用-Wshorten-64-to-32或作为-Wall的一部分?”我不相信有一个好的答案。只需在您的项目中启用这些功能,然后继续。(在C/C++中有很多东西我需要警告或完全禁止,但我会编写一个编译器[用于派生语言]拒绝许多带有默认设置的代码..)您通过编写float res=d明确请求降级;如果编译器警告这一点,我会觉得很烦人。很多这些都归结为开发社区的长期经验。如果许多有经验的程序员被这样的非预期转换所困扰,首先GCC可能会启用警告作为
-Wall
的一部分,然后有人可能会建议更改标准等。。事实上,它没有被警告,这表明很少有人看到你的“潜在的非常危险”有太多的物质。标准允许许多类似的危险转换,总的来说,它们更方便,也更麻烦。谢谢你的回答。的确,我不同意这种行为不危险,但我明白你的意思。例如,我的代码使用双精度,保持这种精度很重要,但我调用的函数之一(或该函数调用的另一个函数)将我的双精度切片为浮点(可能是一个按值接受浮点参数而不是双参数的函数)。在这种情况下,如果知道我的替身被切了,那就太好了。我总是可以使用grep检查演员阵容,但无声降级可能很难检测到。无论如何,谢谢你的回答!