缩小转换和初始化列表,哪个编译器是正确的? [英] Narrowing conversions and initializer lists, which compiler is right?

查看:201
本文介绍了缩小转换和初始化列表,哪个编译器是正确的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的代码:

#include <iostream>

auto main() -> int {
  double x(7.0);
  int i{x};
  std::cout << "i = " << x << std::endl;

  return 0;
}







  • 在GCC4.9中编译时,只编译一条警告:


    • When compiled in GCC4.9 it compiles fine with only a warning:



      警告:缩小{}中的'x'从'double'到'int'的转换





      • 使用Clang3.3或VC ++ 2013进行编译会产生编译错误:

      • Compiling with either Clang3.3 or VC++2013 gives a compile error:



      错误:类型'double'不能缩小到初始化列表中的'int'
      错误C2397:从'double'转换为'int'需要缩小




      • 根据标准,哪些编译器是正确的?

      • Which of the compilers is right according to the standard?

      上述编译器是否有任何理由表现出这种不同的行为?

      Is there any reason why the compilers mentioned above should exhibit such diverse behaviour?

      推荐答案

      答案



      两个编译器都是正确的!

      The answer

      Both compilers are correct!

      标准不区分警告,均位于诊断类别下。

      The Standard doesn't distinguish between an error and a warning, both go under the category of Diagnostics.


      1.3.6 诊断讯息 $ c> [defns.diagnostic]

      1.3.6 diagnostic message [defns.diagnostic]


      消息属于实现的输出消息

      message belonging to an implementation-defined subset of the implementation's output messages


      由于标准规定,如果程序不合格,因为当缩进转换发生在支持初始化程序内时,两个编译器都会确认。

      Since the Standard says that a diagnostic is required in case a program is ill-formed, such as when a narrowing-conversion takes place inside a braced-initializer, both compilers are confirming.

      即使程序从标准的角度来看是错误的,不要求编译器停止编译,因为;一个实施可以随意做任何它想要的,只要它发出诊断。

      Even if the program is ill-formed from the Standards point of view, it doesn't mandate that a compiler halts compilation because of that; an implementation is free to do whatever it wants, as long as it issues a diagnostic.

      有用的信息由 @ Jonathan Wakely 通过对此帖子的评论,以下是两个意见的合并;

      Helpful information was provided by @Jonathan Wakely through comments on this post, below are a merge of the two comments;


      他的确切原因是GCC在一个点上犯了一个错误,它破坏了所有的程序,所以它变成一个警告。对于大型C ++ 03代码库,打开 -std = c ++ 0x 选项的几个人发现无害的缩小转换,导致大部分移植工作转到C + +11

      参见例如 PR 50810 其中Alisdair报告缩小错误率> 95%的问题在彭博的代码库中。

      在同一个PR中,你可以看到,不幸的是,这不是一个让我们发出警告并做它的情况,因为它花了很多时间正确的行为。

      he exact reason is that GCC made it an error at one point and it broke ALL THE PROGRAMS so it got turned into a warning instead. Several people who turned on the -std=c++0x option for large C++03 codebases found harmless narrowing conversions to cause most of the porting work to go to C++11

      See e.g. PR 50810 where Alisdair reports narrowing errors were >95% of the problems in Bloomberg's code base.

      In that same PR you can see that unfortunately it wasn't a case of "let's just issue a warning and be done with it" because it took a lot of fiddling to get the right behaviour.

      这篇关于缩小转换和初始化列表,哪个编译器是正确的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆