c++c++11gccvisual-c++bit-fields

Bitfield struct size different between gcc and MSFT CL


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 ?


Solution

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