c++ - 缩小转换和初始化列表,哪个编译器是对的?

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

考虑以下代码:

#include <iostream>

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

  return 0;
}

  • 在 GCC4.9 中编译时,它编译得很好,只有一个警告:

    warning: narrowing conversion of ‘x’ from ‘double’ to ‘int’ inside { }


  • 使用 Clang3.3 或 VC++2013 编译会出现编译错误:

    error: type 'double' cannot be narrowed to 'int' in initializer list error C2397: conversion from 'double' to 'int' requires a narrowing


问题:

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

  • 上面提到的编译器有什么理由表现出如此多样化的行为吗?

最佳答案

答案

两个编译器都是正确的!


说明

标准不区分错误警告,两者都属于诊断

1.3.6 diagnostic message [defns.diagnostic]

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

由于标准规定在程序格式错误的情况下需要进行诊断,例如在大括号初始化器内发生缩小转换时,两个编译器都在确认。

即使从标准的角度来看程序格式不正确,编译器也不会因此而停止编译;一个实现可以自由地做它想做的任何事情,只要它发出一个诊断。



gcc 行为的原因?

@Jonathan Wakely 提供了有用的信息通过对这篇文章的评论,以下是两条评论的合并;

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.

关于c++ - 缩小转换和初始化列表,哪个编译器是对的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24032430/

相关文章:

c++ - 我应该返回 bool 还是 const bool?

c++ - 清除 vector 会影响其容量吗?

visual-studio - VC++ 2013 运行时 ClickOnce Bootstrap 包

c++ - GCC 的 __attribute__ ((__packed__)) 的 Visual C++ 等效项

c++ - 使用标准模板库列表或 vector 和 multimap 创建电话簿

c++ - 如何迭代每个对象并从 C++ 中的自定义类数组访问其成员函数?

python-3.x - 即使安装了 Microsoft Visual C++ 14.0 也会出现 Pip 错误

c++ - 在模板类中使用模板函数

c - gcc 找不到-lX11

c - 如何让gdb在某些条件下设置断点?