while working with bit shifts on the atmega328 chip under avr-gcc 5.4.0 I noticed a bug(?). Let's see some snippets:
This code works as expected:
uint32_t val = 0xaabbccdd;
Serial.println( val, HEX ); //Output: aabbccdd
// For testing 32 bit variables
This one also works:
uint16_t read = 0x3FF;
uint32_t val = read * 65536;
Serial.println( val, HEX ); // Output: 3ff0000
But this is not!:
uint16_t read = 0x3FF;
uint32_t val = read << 16;
Serial.println( val, HEX ); // Output: 0
(With values less than 16 the system even crashes!)
Is there any known bug in the compiler?
uint16_t read = 0x3FF;
uint32_t val = read << 16;
Since read
is only 16 bit wide and 16 zeroes are shifted in from the right, the result in val
is 0
. You have to use a explicit cast to uint32_t as already suggested in the comments.
uint16_t read = 0x3FF;
uint32_t val = read * 65536;
This works without a cast, because 65536 is handled as an int32_t (because it does not fit into uint16_t) and thus, the result of the multiplication is int32_t and does not overflow.