Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a narrowing conversion warning appear only in case of list initialization?

I have the following code:

class A
{
    public:
        A(const unsigned int val) : value(val) {}

        unsigned int value;
};

int main()
{
    int val = 42;
    A a(val);
    A b{val};       // <--- Warning in GCC, error in Microsoft Visual Studio 2015

    return 0;
}

Why does the narrowing conversion warning appear only in case of list initialization usage?

like image 277
Alex Avatar asked Dec 25 '16 14:12

Alex


People also ask

How do you fix narrowing conversions?

If you make a narrowing conversion intentionally, make your intentions explicit by using a static cast. Otherwise, this error message almost always indicates you have a bug in your code. You can fix it by making sure the objects you initialize have types that are large enough to handle the inputs.

What is a narrowing conversion?

A narrowing conversion changes a value to a data type that might not be able to hold some of the possible values. For example, a fractional value is rounded when it is converted to an integral type, and a numeric type being converted to Boolean is reduced to either True or False .


2 Answers

list initialization was introduced since C++11 with the feature prohibiting implicit narrowing conversions among built-in types. At the same time, the other two "old-style" (since C++98) initialization forms which use parentheses and equal-sign like

int val = 42;
A a(val);
A a = val;

don't change their behavior to accord with list initialization, because that could break plenty of legacy code bases.

like image 68
songyuanyao Avatar answered Oct 09 '22 14:10

songyuanyao


Under the standard, narrowing conversions are illegal in that context. They are legal in the other context. (By "illegal", I mean make the program ill-formed).

The standard requires that a compiler issue a diagnostic in that particular case (of making the program ill-formed). What the compiler does after emitting the diagnostic the standard leaves undefined.

MSVC chooses to halt compilation. Gcc chooses to emit nasal demons pretend the program makes sense, and do the conversion, and continue to compile.

Both warnings and errors are diagnostics as far as the standard is concerned. Traditionally errors are what you call diagnostics that preceed the compiler stopping compilation.

Also note that compilers are free to emit diagnostics whenever they want.

Traditionally warnings are used when you do something the standard dictates is a well formed program yet the compiler authors consider ill advised, and errors when the standard detects an ill-formed program, but most compilers do not enforce that strictly.

like image 43
Yakk - Adam Nevraumont Avatar answered Oct 09 '22 13:10

Yakk - Adam Nevraumont