Narrowing conversions and initializer lists, which compiler is right?

c++, c++11, clang, gcc, visual-c++

Solution

The answer

Both compilers are correct!

Explanation

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

`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.

The reason for gcc's behavior?

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

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.

Problem

Considering the following piece of code: ``` #include <iostream> auto main() -> int { double x(7.0); int i{x}; std::cout << "i = " << x << std::endl; return 0; } ``` When compiled in GCC4.9 it compiles fine with only a warning: `warning: narrowing conversion of ‘x’ from ‘double’ to ‘int’ inside { }` Compiling with either Clang3.3 or VC++2013 gives a compile error: `error: type 'double' cannot be narrowed to 'int' in initializer list` `error C2397: conversion from 'double' to 'int' requires a narrowing` Questions: Which of the compilers is right according to the standard? Is there any reason why the compilers mentioned above should exhibit such diverse behaviour?

Original source