What is causing this 'narrowing conversion' warning? Because I'm still figuring out 'Arduino C' I leave all warnings on.

Recently I got this one:

narrowing conversion of '(int)(((unsigned char)bx_0) | ((unsigned char)bx_1))' from 'int' to 'const byte... etc.

...referring to this line:

const byte pinMask[3] = {bx_0, bx_1, bx_0 | bx_1};


...pointing to the or symbol.

The code in question (much simplified to recreate this):

const int latch[2] = {2, 4};

const byte bx_0 = 1 &lt;&lt; latch[0];
const byte bx_1 = 1 &lt;&lt; latch[1];

const byte pinMask[3] = {bx_0, bx_1, bx_0 | bx_1};


(This happens whether I use byte, uint8_t, or unsigned char everywhere.)

Without the or operator, no warning. If bx_0 and bx_1 are simple bytes, not shifted into existence, no warning. If I do this:

const byte pinMask[3] = {bx_0, bx_1, (byte)(bx_0 | bx_1)};


...again, no warning. 

However, I get no complaints about this:

const byte notMask = !(bx_1 | bx_0);


...so a further condition is that the problem or has to be in an initializer list. Yikes.

I don't get it. There's no way an or of two bytes can force widening, so where did the (int) cast come from? It apparently has something to do with the 1 &lt;&lt; latch[0] code, but the result of that is still a byte, by definition.

I have a solution -- the (byte) cast -- but in the real code it's ugly and feels unnecessary. Everything is already just bytes.
That warning message arises when a compiler complies with C/C++ specifications.  

According to ISO/IEC 9899:2011 part 6.5.12.2 (“Bitwise inclusive OR operator”),


  Each of the operands shall have integer type


Thus, in the evaluation of bx_0 | bx_1 within the statement const byte pinMask[3] = {bx_0, bx_1, bx_0 | bx_1};, the operands bx_0 and bx_1 are converted to int type before being OR'd together.  This produces an int result, which then must be narrowed to byte before it can be stored in the  byte array.

Knowing that the (byte) cast is necessary because of C/C++ specifications should convert your view of the cast from “ugly” and “unnecessary” to “necessary” and either “ok” or “oh well”.  :)