question

Cnks-9146 avatar image
0 Votes"
Cnks-9146 asked ·

Why this is ok?

in my book: C++ primer plus , it says that
"""
long plifs[] = {25,92,3.0};
"""
is not allowed.

but I can use it.

c++
· 1
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


Which edition and chapter says that?

0 Votes 0 ·
JeanineZhang-MSFT avatar image
0 Votes"
JeanineZhang-MSFT answered ·

Hi,

As far as I'm concerned you couldn't ignore the warning generated by the compiler. Here the compiler will generate Compiler Warning (level 1) C4838 .

In general, for violations of the language rules, the C++ standard requires that the compiler issue a diagnostic. It did that. The Standard specifies that a diagnostic is required in case that a program is ill-formed. Which is the case when a narrowing-conversion takes place inside a braced-initializer.

According to the Doc: Implicit type conversions

If the selected conversion is a promotion, the compiler does not issue a warning. If the conversion is a narrowing, the compiler issues a warning about possible data loss. Whether actual data loss occurs depends on the actual values involved, but we recommend that you treat this warning as an error.

Best Regards,

Jeanine Zhang



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Yeah, I think you are right.
This warning should treat as error.

And in Microsoft docs it shows "the compiler issues a warning".
I think that's the problem. Just because of some unknown reasons,
What wasn’t allowed in C++ 11 became a warning in VS 2019.
(Maybe the compiler, maybe some of my sets or something else)

Thanks.

0 Votes 0 ·
cooldadtx avatar image
1 Vote"
cooldadtx answered ·

The book is wrong if it says that is not OK. Not sure what the book says is not valid about this but it has always been valid in C++. The array is implicitly sized because you didn't specify the size in the declaration. Therefore it'll use the size of the array you're assigning to it (which is required). Curly braces with values separated by commas indicates an array. You are assigning the 3 element array to the plifs array. Therefore that array will have an implicit size of 3.

The only thing that remotely stands out as potentially an issue is the last element in the array is a double. This requires the compiler to truncate the double to a long. In C this was allowed for array initialization and therefore C++ allows it as well. However C++ will generate a warning letting you know that you're potentially losing data. It is important to always look at compiler warnings to ensure they may not be indicating something is wrong with your code. Many companies have a "clean build" policy when it comes to warnings for good reasons.

· 5 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Well, Thanks.
But it is the most famous book in my country.
So I do not think it's wrong.
And a lot of rules of C has changed in C++.

Before, it says that
"""
int a = {3.2};
"""
is not allowed.
Because it's a "Narrowing change" which not allowed to used in"{}".
(in book it writes "List initialization forbids narrowing changes")

And in fact, it does.
So, I don't thinks wrong.

Maybe C++11 has changed something recently, I guess.
76505-1.png
Thanks.




0 Votes 0 ·
1.png (805.1 KiB)

It seems that it is a required limitation since c++11 — https://en.cppreference.com/w/cpp/language/list_initialization (Narrowing conversions) — which is currently shown as a warning. Other compilers display an error, which is probably more conformant. You can investigate some other on-line compilers to see the differences.

1 Vote 1 ·

Thanks.
And I think that's the problem.
C++ 11 not allowed this convertion, but in different compilers it shows different contents.

0 Votes 0 ·

C++ has always allowed this because C allows it. You can refer to the C and C++ specs for this if you'd like to confirm.

Your second example is not allowed but not because of the narrowing issue, although the compiler reports it that way. a is not an array, it is an int variable. You are attempting to assign an array value to it. If you change to this int a = { 3, 2 }; you'll get the error. However C/C++ allows you to wrap a single value in curly braces and it basically ignores the curly braces (that is why you can use curly braces inside multi-dimensional array initializers or not)).

In your case the compiler sees your code as the same as int a = 3.2 which is a narrowing conversion error. As stated earlier C/C++ allows narrowing in arrays, not single variables like a.

Nevertheless the first example is valid, with a warning, in all versions of C/C++.

0 Votes 0 ·

Well, thanks again.
But I must say "C/C++ allows narrowing in arrays (when list-initialization)" is wrong.
In C++ 11, it says
"""
Narrowing conversions
list-initialization limits the allowed implicit conversions by prohibiting the following:

conversion from a floating-point type to an integer type
"""
And I found thiswhy-compiler-allows-narrowing-conversions
I think that's the problem, because

language definition doesn't distinguish between warnings and errors


And In visual studio 2019, it's a warning.

Thanks.





0 Votes 0 ·