avr-gcc

Is there a bug when bit-shifting on the avr-gcc compiler?


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?


Solution

  •    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.