std::string has constructors declared as:
string::string(std::initializer_list<char>); string::string(std::size_t, char);
When we have list initialization, the following rule applies:
(N3337 [dcl.init.list]/3): An initialization list of an object or link of type T is defined as follows:
- [...]
- Otherwise, if T is a class type, constructors are considered. The constructors used are listed and the best one is selected using overload resolution (13.3, 13.3.1.7). If narrowing the conversion (see below) is required to convert any of the arguments, the program is poorly formed.
The initializer list constructor is selected because of this rule:
(N3337 [over.match.list]/1): When objects of a non-aggregate type T are initialized by a list (8.5.4), the overload resolution is selected by the constructor in two phases:
- Initially, candidate functions are initializer-list constructors (8.5.4) of class T, and the argument list consists of a list of initializers as a single argument.
- [...]
Now, since the constructor of the initializer list is the best choice, but a narrowing conversion is required to convert the argument, the program is poorly formed.
However, I do not think that one compiler is correct and one is incorrect:
(N3337 [intro.compliance]/8): corresponding implementation may have extensions (including additional library functions) if they are executed and do not change the behavior of any well-formed program. Implementations are needed to diagnose programs that use extensions that are poorly formed in accordance with this International Standard. However, by doing this, they can compile and execute such programs.
The standard does not have the concept of warning and error, so GCC is compatible with the issuance of diagnostic diagnostics, and then still collects the program. Note that GCC will -pedantic-errors error if you pass -pedantic-errors .
source share