On 2021-04-12 02:46 +0000, He Leon via Gcc-help wrote: > Hi all, > > I meet an issue of integral promotion. I have small APP as appended. > > The bit-fields integral promotion(***shift = fl_a.e << 28***) result is > different between Linux and windows. > a) Linux gcc: fl_a.e is promoted as integer, and shift result is > "0xffffffffe0000000", /* snip */ > #include <stdio.h> > > typedef union > { > struct { > unsigned long long m : 28; > unsigned long long e : 8; > unsigned long long s : 1; > }; > unsigned long long hex : 37; > } fl; > > int main() > { > unsigned long long shift = 0; > unsigned long long cast_shift = 0; > fl fl_a; > > fl_a.m = 0; > fl_a.e = 0x7e; > fl_a.s = 0; > > shift = fl_a.e << 28; You are invoking undefined behavior here. -fsanitize=undefined reports: t.cc:23:19: runtime error: left shift of 126 by 28 places cannot be represented in type 'int' As the compiler can do "anything" for UB, there is no way to say who is correct or who is wrong. > cast_shift = ((unsigned long long)fl_a.e) << 28; > > printf("%s() (a<<28)-0x%llx, ((uint64)a<<28)-0x%llx\n", __func__, shift, > cast_shift); > > return 0; > } > -- Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University