0

So I have a data structure that entirely consists of :

  • unsigned char i.e. byte-sized attributes
  • bool_T which I have typedefd to unsigned char (if C) or to bool (if C++) so again byte-sized
  • enums which contain no more than 5 entries and should therefore be byte-sized as well.

However, next to each enum, Qt Creator puts one of those pre-analysis hypothetical warnings (the symbol is a yellow triangle that's empty - only the contour of it) about padding the data structure with some bytes with the aim, I gather, to align the next element in the structure.

How does that make any sense, since this is (or should be) all bytes ? Are my enums not bytes ? Can I force the compiler to make them bytes ? Can I force the compiler to not align in some cases, or does the C standard prohibit this ?

More info : I am writing C89, using Qt 5.12.11, Qt Creator 4.15.0 (based on Qt 5.15.2), CMake 3.19.4 with Ninja 1.10.2 and compiling with minGW/gcc 7.3.0.

Thanks !

Charles
  • 988
  • 1
  • 11
  • 28

1 Answers1

0

C++ nowadays has the possibility to specify the underlying type of an enum, but that's quite new (C++11, not C99 let alone C89). So no, you can't assume it's a byte, nor can you directly force it. But you can use bitfields (:3 is enough for up to 8 values)

Also, bool in C++ is not byte-sized by definition; it can be bigger.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • That's what I feared. Also a couple of `sizeof`s showed that all my `enums` require 4 bytes. Which makes no sense but okay. – Charles Feb 21 '22 at 08:30
  • @Charles: Chances are your `sizeof(int)==4` as well. C didn't have an explicit, literal _underlying type_ for enums, but many compilers did use `int` as the underlying type by default. This is useful e.g. when passing an `enum` in a register. – MSalters Feb 21 '22 at 10:27
  • Yes yes it's a standard 32-bit app. But why is using `int` easier when passing over a register ? Is this specific to `enum`s, or are you simply talking about how generally smaller types must be anyways extracted from a 4-byte word on most 32-bit architectures, which requires a few more operations (masking, shifting) on top of the reading ? – Charles Feb 21 '22 at 12:23
  • @Charles: Implementors have to consider the ABI; how the abstract language maps to the CPU. Where can function `void foo(enum E)` find the argument E? Stack? Register? It turns out that this simplifies when the ABI can simply say "see the earlier paragraph on ints". Note that this is just an implementation detail, other ABI's might differ. You can't rely on `sizeof(enum Foo)==sizeof(int)`. – MSalters Feb 21 '22 at 13:52