mercredi 19 juin 2019

Why is this specific narrowing conversion not detected?

when constructing variables using the list-initialization (like int x{ 5 }) the standard §8.5.4 says:

If a narrowing conversion […] is required to convert any of the arguments, the program is ill-formed. (7) A narrowing conversion is an implicit conversion - (7.4) from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

So why does this compile?

char c{ 'A' };
char x{ c + c };


As a reminder, c + c yields an int

static_assert(std::is_same_v<decltype(c + c), int>, "");

so the compiler should complain about a narrowing conversion which is certainly not a constant expression.


Interestingly, declaring x to be an unsigned char correctly fails to compile:

char c{ 'A' };
unsigned char x{ c + c }; 

C2397 conversion from 'int' to 'unsigned char' requires a narrowing conversion

As does introducing a temporary:

char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]


So why does the first version compile? I am using Visual Studio Community 2017 Version 15.9.5. Is it a Visual Studio bug?

Aucun commentaire:

Enregistrer un commentaire