# Why is char being "extended" to an int?

I know I'm missing something so simple here, but I can't figure it out.

If I do `char letter = 'A';` then `letter = letter << 8`, letter = 0, as one should expect, since we are shifting the bits "off the shelf" to the left.

But, if we do this:

``````char letter = 'A';

void setup()
{
Serial.begin(9600);

int twoBytes = letter << 8;
Serial.println(twoBytes, BIN);

}

void loop() {}
``````

The result is 100000100000000, but why? `<<` has precedence over `=`, so it should be bitshifting `letter` left by 8 first, then assigning that value (which should be 0) to `twoBytes`.

• Isn't there an implication that it will work (for some definition of "work")? If you were expecting zero why not just write: `int twoBytes = 0;` - the fact that you didn't implies that you expect letter to be treated as 16 bits. Commented Sep 20, 2023 at 6:05
• I just want to point out that although you posted it here, this is entirely a C++ question. The Arduino compiler is the GNU C++ compiler. Nothing "Arduino" about the way it treats code you write, with the exception of some pre-processing that the IDE does. See here for more details about that. Commented Sep 20, 2023 at 6:11
• @NickGammon .....because I need `letter` to be in high byte of `twoBytes`, and I'm putting another char into the low byte of `twoBytes`. Even though the code I wrote worked, being the inquisitive person I am I realized it didn't make sense, hence the question. Commented Sep 20, 2023 at 15:00

This is a funny, non-intuitive rule of the C++ language called “integral promotion”. Simply stated, it says that no computation is ever performed on a type smaller than `int`: anything smaller gets implicitly promoted to `int` as soon as it appears in an arithmetic or logic expression.
• Thank you, I'll take it on faith! Would it be good practice to say `int twoBytes = letter; twoBytes << 8;` instead for clarity, or does it even matter? Commented Sep 19, 2023 at 16:26
• I would say that, for an experienced C or C++ programmer, it may not really matter. For someone unfamiliar with these rules, anything that can make the code clearer is a good thing. You may also write `int twoBytes = int(letter) << 8;`, or you may stick with `letter << 8` and add a comment. Commented Sep 19, 2023 at 17:10
• In this sort of case, where you only want the right-most 8 bits I would personally "and" it, like this: `int twoBytes = (letter << 8) & 0xFF;` Since you want the low-order byte, make it explicit. Commented Sep 20, 2023 at 3:30
• I'm not sure how what you're saying is connected to what they're saying, but `int twoBytes = (letter << 8) & 0xFF;` is either complicated way of putting zero in `twoBytes` or potentially undefined behavior, depending on the value and system. Commented Sep 20, 2023 at 17:41