I have following question: e.g. I have given code:
uint8_t a = 0x30;
uint16_t b = a << 8;
Will a
be first shifted and then converted to uint16_t
? Or will it be converted to uint16_t
first? Or is this behavior compiler dependent? I'm trying to build a uint16_t
given lsb and msb separately as uint8_t
s.
P.S. I didn't know this behavior depended on whether it's C or C++, could someone please tell how it will work in both cases?
Expression evaluation in C is bottom up in the expression tree, that is in your case
a << 8
is evaluated first (obviously) before being used as initializer. C's type system follows this evaluation, but see below, so the type on the right of the=
has nothing to do with the type on the left. It is only for the initialization that the type itself is adjusted with an implicit conversion.That said, things are more complicated here for
a << 8
than they look at a first glance, because you chose a type fora
that is (most likely) a narrow type. So on most architecturesuint8_t
as it is narrower thanint
will be promoted to that in any arithmetic expression.So here in your case that would give you an
int
, thus the left shift with8
works well, and then theint
is converted touint16_t
.Had you chosen an constant for
a
with HO bit1
, the picture would be different. Depending on the architecture (ifint
is 16 bit) this could then shift a1
into the sign bit and the behavior would be undefined.All these complicated arguments show, that it is in general not a good idea to do arithmetic with narrow integer types.