3

When I try to compile this code

struct T
{
    unsigned char x;
};

int main()
{
    unsigned char a = 10;
    unsigned char b = 1;

    T t = {a + b};

    return 0;
}

I get this error:

error: narrowing conversion of '(((int)a) + ((int)b))' from 'int' to 'unsigned char' inside { } [-Wnarrowing]|

Can anyone explain me why?

DarkoNaito_09
  • 71
  • 2
  • 12

1 Answers1

4

The operands to your addition expression are undergoing integral promotion.

In particular, arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value.

Your a and b are being promoted to int or unsigned int, added, and then converted back down to unsigned char.

If the conversion is expected program behavior (from your point of view as the designer), you can explicitly cast it to the type you want. An explicit cast is not a narrowing conversion. An implicit cast is. So if we change the implicit cast to an explicit cast, the program is no longer ill-formed.

T t = { static_cast<unsigned char>(a + b) };
JohnFilleau
  • 4,045
  • 1
  • 15
  • 22
  • so... how can I resolve this? btw, i had never heard of this before – DarkoNaito_09 Mar 07 '20 at 18:08
  • 2
    It you find it acceptable, you can [set the error to a warning](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55783) Or just cast `T t = { (unsigned char)(a + b) }; ` – lakeweb Mar 07 '20 at 18:09
  • 1
    Not sure, let me look it up. What compiler are you using? My first guess is that an explicit `T t = { static_cast(a + b) };` might fix it, because then the compiler doesn't think you're making a mistake. – JohnFilleau Mar 07 '20 at 18:10
  • I'm using GCC 8.2.0 – DarkoNaito_09 Mar 07 '20 at 18:14