微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 为什么没有clang警告从double到int的隐式转换,但是从long到int时会这样做?

在以下代码中:
#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
}

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

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

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

解决方法

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

从long int到int的转换可能或者可以工作或者可能是未定义的行为,具体取决于平台和值(唯一的保证是int不大于long int,但它们可能是相同的大小).

换句话说,整数类型之间的转换中的问题是实现的偶然工件,而不是设计决策.关于它们的警告更好,特别是如果在编译时可以检测到由于这些限制而无法正常工作.

另请注意,即使从double到int的转换也是合法且定义良好的(如果在边界内完成),即使在编译时可以看到精度损失,也不需要实现来警告它.编译器即使在使用可能有意义时也会发出太多警告可能是一个问题(你只是禁用警告,甚至更糟糕的是养成接受非正常构建的习惯).

这些隐含的转换规则可能与其他C皱纹相结合,变得真正奇怪且难以证明行为,例如:

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

不要试图用C过多的逻辑.阅读规格效果更好.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐