c++ - 为什么 clang 不警告从 double 到 int 的隐式转换,而是在从 long 到 int 时警告?

标签 c++ c++11 gcc clang gcc-warning

在下面的代码中:

#include <iostream>
int main()
{
  const long l = 4294967296;
  int i = l;
  return i; //just to silence the compiler
}

编译器警告隐式转换(使用 -Wall 和 -std=c++14)如下:

warning: implicit conversion from 'const long' to 'int' changes value from 4294967296 to 0 [-Wconstant-conversion]

没关系。但是如果是double转int则没有警告,如下代码:

#include <iostream>
int main()
{
  const double d = 4294967296.0;
  int i = d;
  return i; //just to silence the compiler
}

为什么编译器在这些情况下会有不同的 react ?

注1:clang版本为3.6.2-svn240577-1~exp1

注意 2:感谢 Compiler Explorer (gcc.godbolt.org),我已经使用许多其他版本的 gcc、clang 和 icc 对其进行了测试。因此,所有经过测试的 gcc 版本(5.x 除外)和 icc 都发出了警告。没有 clang 版本做到了。

最佳答案

double 到整数类型的转换会“按设计”更改值(将 3.141592654 转换为 int)。

long intint 的转换可能有效,也可能是未定义的行为,这取决于平台和值(唯一的保证是 >int 不大于 long int,但它们的大小可能相同)。

换句话说,整数类型之间的转换问题是实现的附带问题,而不是设计决定。对它们发出警告会更好,尤其是当可以在编译时检测到由于这些限制而导致某些功能无法正常工作时。

另请注意,即使从 doubleint 的转换也是合法且定义明确的(如果在边界内完成),并且不需要实现即使在编译时可以看到精度损失,也要警告它。即使使用可能有意义,编译器也会发出过多警告,这可能是一个问题(您只是禁用警告,或者更糟的是养成了正常接受非干净构建的习惯)。

这些隐式转换规则可能会与其他 C++ 皱纹相加,变得非常奇怪且难以证明行为的合理性,例如:

std::string s;
s = 3.141592654; // No warnings, no errors (last time I checked)

不要尝试在 C++ 中使用过多的逻辑。阅读规范效果更好。

关于c++ - 为什么 clang 不警告从 double 到 int 的隐式转换,而是在从 long 到 int 时警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39282602/

相关文章:

c++ - Netbeans C++ : Execute a source script before building

c - 如何指示可以使用内联ASM参数*指向*的内存?

gcc - C 程序的数据流图生成

c++ - C++中运算符重载的问题

c++ - getline 设置 failbit 和 eof

C++ 模板元编程, "static if"解决方法 - 可以改进吗?

c++ - 将 vector<T> 转换为 initializer_list<T>

c++ - 如何最好地将 GCC 与 Visual Studio 结合使用

c++ - 指向 vector 的变量

c++ - Variadic 函数和 C++11,将对象作为参数传递