3

Clang: 3.8.0 MSVC: 19.00.24215.1 for x64

What could be causing this strange difference between the compilers? MSVC reports 12, but Clang reports 8! What's the correct/expected behaviour here? Does the standard have anything to say about this?

enum class CodeCompletionDeclKind {};

struct SwiftSemanticToken {
  unsigned ByteOffset;
  unsigned Length : 24;
  CodeCompletionDeclKind Kind : 6;
  bool IsRef : 1;
  bool IsSystem : 1;
};
static_assert(sizeof(SwiftSemanticToken) == 8, "Too big");

int main()
{
    std::cout << "Hello, world!\n";
}
H Bellamy
  • 22,405
  • 23
  • 76
  • 114
  • 2
    Size of structures containing bit fields are Implementation defined. See the notes section in: http://en.cppreference.com/w/cpp/language/bit_field Specifically implementation defined: _"Everything about the actual allocation details of bit fields within the class object"_ – Richard Critten Feb 18 '17 at 10:48
  • @RichardCritten: Why not write an answer instead of a comment? – Christian Hackl Feb 18 '17 at 11:12
  • @ChristianHackl Was on a phone, formatting is frustrating – Richard Critten Feb 18 '17 at 12:06

1 Answers1

2

The size of your class object containing bit fields will be implementation defined.

class.bit/1:

...Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others.  — end note ]

WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • Thanks, I'll accept your answer in a sec, but first: what is Clang doing here to make the struct size 8. Is there a way (e.g. by doing unsigned ByteOffset : 1;) to force MSVC to make this an 8 byte struct? I need this behaviour as it is used for serialization – H Bellamy Feb 18 '17 at 12:51
  • @HBellamy, Clang and GCC are obviously smart enough to share all the bit field members across 8bytes. MSVC on the other hand doesn't pack them that tightly; even when asked to discard alignment for some reasons I don't know about. I was only able to get it to 9bytes as seen [here](http://rextester.com/FHN35966). Also, see [this](http://stackoverflow.com/questions/3919194/what-is-vc-doing-when-packing-bitfields). Whatever size the compiler uses is correct according to the C++ standard. – WhiZTiM Feb 18 '17 at 15:21