you can go around about ... make a temporary one, set it to -1 and take a rounded log2 or something...
but you know this. You defined it. Stow that somewhere if you need it back?
sizeof is in bytes. its not defined because that don't make no sense for a 3 bit value.
When the type changes (ie int to bool (1 byte)) there is a new byte/word etc started. That's why having the same type for all of the bits gives the expected result. uint32_t gives 4 and uint8_t gives 1.
Poke-a-hole, pahole(1), is a tool that reports the layout of structures as they appear in a binary. See its manual page: https://linux.die.net/man/1/pahole
A possible output is:
Why is it so important to know the size of the struct? I would have thought that if one was going to write it to a binary file say, then it is up to the coder to know the sizes of the individual items and write/ read them accordingly. It seems to me, to rely on the size of a struct or it's layout is a rabbit hole.
The default pack size I think is 4 for 32 bit and 8 for 64 bit. pack size is the minimum into which elements are packed. So the first 3 are packed into an int (4 bytes on that system) and then the 4 bools are packed into another 4 bytes - ie 8 bytes. With pack 1, then the first 3 are still packed into 4 bytes but now the bools are packed into 1 byte - hence 5 bytes.
Why is it so important to know the size of the struct?
I, of course, don't know the reason why it is important to frek, but one possible application is for code that is optimized for cache performance, which can make significant improvements if done correctly. If you guarantee that your struct is 4 bytes large, then that means you can pack an array of 16 of these objects into one cache line (many cache lines are 64 bytes wide).