Reputation: 1497
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?
Upvotes: 0
Views: 92
Reputation: 78903
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 for a
that is (most likely) a narrow type. So on most architectures uint8_t
as it is narrower than int
will be promoted to that in any arithmetic expression.
So here in your case that would give you an int
, thus the left shift with 8
works well, and then the int
is converted to uint16_t
.
Had you chosen an constant for a
with HO bit 1
, the picture would be different. Depending on the architecture (if int
is 16 bit) this could then shift a 1
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.
Upvotes: 4