Honestly, with your samples, I see little wrong.
However, there are a number of cases where the compiler apparently accepts "violations" of the standard conversion rules ...:
Initializer Lists (Β§ 8.5.4)
However, I noticed this in the standard:
For initial lists is not permissible (Β§ 8.5.4, under 3. )
int ai[] = { 1, 2.0 };
Section 6. The following is a general list of examples:
[Note. As indicated above, such conversions are not allowed at the top level in the initialization list.-End note]
int x = 999; // x is not a constant expression const int y = 999; const int z = 99; char c1 = x; // OK, though it might narrow (in this case, it does narrow) char c2{x}; // error: might narrow char c3{y}; // error: narrows (assuming char is 8 bits) char c4{z}; // OK: no narrowing needed unsigned char uc1 = {5}; // OK: no narrowing needed unsigned char uc2 = {-1}; // error: narrows unsigned int ui1 = {-1}; // error: narrows signed int si1 = { (unsigned int)-1 }; // error: narrows int ii = {2.0}; // error: narrows float f1 { x }; // error: might narrow float f2 { 7 }; // OK: 7 can be exactly represented as a float int f(int); int a[] = { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
Interestingly, g ++ 4.6.1 with --std=c++0x -Wall -pedantic
catches only one of these violations:
char c3{y};
Outside of initializer lists ...
I do not think that truncating a float in an int is considered narrowing
.
This is just a well-defined transformation, similar to
int i = 31; i /= 4; // well defined loss of precision... i /= 4.0; // equally well-defined conversion from floating point to int
source share