mardi 28 juillet 2015

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

I learnt about curly-brace-delimited initializer in The C++ Programming Language, 4th ed. > Chapter 2: A Tour of C++: The Basics.

I am quoting from the book below.

The = form is traditional and dates back to C, but if in doubt, use the general {} -list form (§6.3.5.2). If nothing else, it saves you from conversions that lose information (narrowing conversions; §10.5):

int i1 = 7.2;    // i1 becomes 7
int i2 {7.2};    // error : floating-point to integer conversion
int i3 = {7.2};  // error : floating-point to integer conversion (the = is redundant)

However, I am unable to reproduce these results.

I have the following code.

#include <iostream>

int main()
{
    int i1 = 7.2;
    int i2 {7.2};
    int i3 = {7.2};

    std::cout << i1 << "\n";
    std::cout << i2 << "\n";
    std::cout << i3 << "\n";
}

When I compile and run it, I don't get any error. I get a warning about std=c++11 but no error.

$ g++ init.cpp 
init.cpp: In function ‘int main()’:
init.cpp:6:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     int i2 {7.2};
            ^
$ ./a.out 
7
7
7

Further, the warning is only for the second assignment but there is no warning for the third assignment. This seems to indicate that the = is not really redundant as mentioned in the book. If = were redundant, either both the second and third assignments would have produced warnings or both would not have produced warnings. Then I compile them with the -std=c++11 flag.

$ g++ -std=c++11 init.cpp 
init.cpp: In function ‘int main()’:
init.cpp:6:16: warning: narrowing conversion of ‘7.2000000000000002e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
     int i2 {7.2};
                ^
init.cpp:7:18: warning: narrowing conversion of ‘7.2000000000000002e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
     int i3 = {7.2};
                  ^
$ ./a.out 
7
7
7

Still no error. Only warnings. Although in this case the second and third assignments behave identically with respect to generating warnings.

So my question is: Although the book mentions that the second and third assignments are errors, why doesn't this code fail to compile?

Aucun commentaire:

Enregistrer un commentaire