I've encountered a rather peculiar behavior in gcc (see below) and I'm
unsure where to inquire about this. Would this be the correct place?
When combining two int32_t with the bitwise-or operator into an int64_t,
I've noticed that the less-significant 32 bits will contain something
extra which will pollute the more-significant bits.
gcc version/OS: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Steps to reproduce:
1. Compile example in attachment:
gcc -Wall incorrect_bitshifting.c
No warning / error output.
2. Run with ./a.out
output:
Higher, lower: aaaa, aaaaaaaa
result: ffffffffaaaaaaaa
original: aaaaaaaaaaaa
Expected behavior:
Result matches original.
Actual behavior:
The upper 32 bits are polluted.
Work-around:
bitwise-and ing the lower 32 bits will provide the correct result:
(int64_t)high_part << 32 | low_part & 0xFFFFFFFF
#include <stdio.h>
#include <stdint.h>
int main( void )
{
int32_t high_part;
int32_t low_part;
int64_t together;
const int64_t id = 0xAAAAAAAAAAAA;
high_part = id >> 32;
low_part = id & 0xFFFFFFFF;
together = (int64_t)high_part << 32 | low_part;
printf("Higher, lower: %x, %x\n", high_part, low_part);
// Higher, lower: aaaa, aaaaaaaa
printf("result: %lx\n", together);
// result: ffffffffaaaaaaaa
printf("original: %lx\n", id);
// original: aaaaaaaaaaaa
}