Why doesn’t narrowing conversion used with curly-brace-delimited initializer cause an error?

This is ill-formed and there should be diagnostic, however it can either be a warning(which you received) or an error. gcc made this a warning for several versions due to porting issue from C++03:

The standard only requires that “a conforming implementation shall issue at least one diagnostic message” so compiling the program with a warning is allowed. As Andrew said, -Werror=narrowing allows you to make it an error if you want.

G++ 4.6 gave an error but it was changed to a warning intentionally for 4.7 because many people (myself included) found that narrowing conversions where one of the most commonly encountered problems when trying to compile large C++03 codebases as C++11. Previously well-formed code such as char c[] = { i, 0 }; (where i will only ever be within the range of char) caused errors and had to be changed to char c[] = { (char)i, 0 }

but now recent versions of gcc and clang make this an error, see it live for gcc.

For reference the draft C++11 standard section 8.5.4 [dcl.init.list] says:

Otherwise, if the initializer list has a single element, the object or
reference is initialized from that element; if a narrowing conversion
(see below) is required to convert the element to T, the program is
ill-formed. [ Example:

int x1 {2}; // OK
int x2 {2.0}; // error: narrowing

—end example ]

and:

A narrowing conversion is an implicit conversion

  • from a floating-point type to an integer type, or

[…]

[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations.—end
note ] [ Example:

[…]

int ii = {2.0}; // error: narrows

[…]

So a floating point to integer conversion is a narrowing conversion and is ill-formed.

and section 1.4 Implementation compliance [intro.compliance] says:

Although this International Standard states only requirements on C++ implementations, those requirements
are often easier to understand if they are phrased as requirements on programs, parts of programs, or
execution of programs. Such requirements have the following meaning:

[…]

  • If a program contains a violation of any diagnosable rule or an occurrence of a construct described in
    this Standard as “conditionally-supported” when the implementation does not support that construct,
    a conforming implementation shall issue at least one diagnostic message.

[…]

Tells us that only a diagnostic is required.

Leave a Comment