I have the following code:
#include <cstdint>
#pragma pack(1)
using MyType_t = union {
uint8_t buffer[16];
struct {
uint64_t a : 55;
uint64_t b : 24;
uint64_t c : 1;
uint64_t d : 48;
}fields;
};
#pragma pack()
int main()
{
return sizeof(MyType_t);
}
I'm getting different result between gcc\clang and Visual C++ (Microsoft CL), when I compare the assembly code in Compiler Explorer and I got the following:
clang (-std=c++11 -O3 )
main: # @main
mov eax, 16
ret
x86-64 gcc 6.3 (-O3)
main:
mov eax, 16
ret
x86-64 CL 19 2017 RTW (-Ox)
main PROC
mov eax, 24
ret 0
main ENDP
is it Visual C++ compiler bug or it is undefined behavior ?
I believe this is undefined behavior. @NathanOliver has the right answer: GCC and Clang are spanning the two uint64_t
values. There's a cost when you read it though: see this very similar code sample on the Compiler Explorer where GCC now has to read two fields and do some math to give second value.