Day 133: Underlying enum type

As far as I am aware C++ standard does not specify the underlying type of an enum except by saying that it is an integral type that can represent all the enumerator values. Now I do realize that a compiler would typically align variables to 32-bit boundaries but since it is supposed to be platform independent code I wonder if it is safe to cast them to uint32 for AtomicCompareExchangeUInt32? I assume specific compiler options and #pragma pack can be ignored for now.

Also, since asset information is now stored in the transient memory (not on a stack) does one need to ensure that those asset_state variables are properly aligned for _InterlockedCompareExchange?
Yeah, enums kind of suck in C. You really want them to be typed, but I think that wasn't introduced until the very latest C++ spec, if I'm not mistaken :(

The transient memory alignment is already forced to be at least 4 (we added this just recently - not sure if you saw that). So it cannot fall between two cache lines, so _InterlockedCompareExchange should be fine.

As for the compiler, yes, there is no explicit spec for the enum size, but we know that it will be at least padded to 32 in the case of that struct (on 32-bit Windows) or 64 (on 64-bit Windows).

If you're concerned about it, you can certainly just change it to a uint32 directly. The enum part is just to add a little compile-time checking, but we don't really need it.

- Casey
I am not too concerned about it since the code obviously runs fine. I was simply wondering if it is a reasonable assumption for most platforms and compilers. Thank you for your explanation.

I believe you are talking about alignment argument for allocations from memory arena. It looks like game_assets as well as transient_state are simply some offsets from game memory allocated by VirtualAlloc or am I wrong?
That is not a reasonable assumption. Some time I had need to compile code where compiler assumed enum is 1 byte long. Common trick to "fix" that is to force enum type to always have 32-bits:
1
2
3
4
5
6
7
enum foo
{
  value1,
  value2,

  dummy_value_force_32_bits = 0x7fffffff,
};

Edited by Mārtiņš Možeiko on
Yes, just to be clear, it's _because it is in a struct with a pointer_ that I said it would be padded. In the case where you are just using it randomly, and there is no spec requirement for padding like there is in a struct, then it could make it as small as the largest value in the enumerant.

- Casey