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;
}
Questions:
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.