Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I try to compile the following code with gcc and C++11 enabled:

unsigned int id = 100;
unsigned char array[] = { id % 3, id % 5 };

I get these warnings:

narrowing conversion of ‘(id % 3u)’ from ‘unsigned int’ to ‘unsigned char’ inside { } [-Wnarrowing]

see demo online

Is there a way to help the compiler find out that the result of id % 3 fits into an unsigned char?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
539 views
Welcome To Ask or Share your Answers For Others

1 Answer

In this specific case making id const or constexpr will fix the problem:

constexpr unsigned int id = 100;

since there is an exception for the case where you have a constant expression whose result after conversion will fit into the target type.

In the more general case you may also use static_cast to cast the result to unsigned char:

{ static_cast<unsigned char>( id % 3), static_cast<unsigned char>( id % 5) }
  ^^^^^^^^^^^                          ^^^^^^^^^^^

We can find he exception for constant expressions and narrowing conversions in the draft C++ standard section 8.5.4 List-initialization which says:

A narrowing conversion is an implicit conversion

and include the following bullet (emphasis mine):

  • 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.

Note, the wording changed from the original draft C++11 standard to what I quote above due to defect report 1449.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...