Created attachment 21570 [details] Small reproducer In the file include/atomic typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order; static_assert((is_same<underlying_type<memory_order>::type, unsigned>::value), "Underlying type differs from unsigned unexpectedly"); when compiling with "g++ -std=c++11 -fshort-enums" the underlying type reduces to unsigned char, and the assert fails. -- A quick fix would be set the last value to something that won't fit in a uchar... memory_order_seq_cst = 0xFFFFFFFF
We just changed this for C++20 - changed to an enum class with an underlying type. Still a problem for C++17 and before. I think the question that needs answering is: Should the size of a memory_order change when `-fshort-enums` is specified? It's clearly NOT going to change when compiling for C++20.
IOW, we used not to specify an underlying type for this enumeration. Hence, the underlying type of the enumeration was `unsigned int` normally, and `unsigned char` when `-fshort-enums` was used. By specifying an underlying type in C++20, we are forcing the underlying type to be `unsigned int` regardless of `-fshort-enums`. This is technically an ABI break for users of `-fshort-enums`. I'm not sure we care about that specific ABI break because I don't think anyone that is using -fshort-enums is realistically relying on the size of the memory_order enumeration. However, I would still be tempted to remove the underlying type since it does not really buy us much. It creates a discrepancy between the C++20 and the non-C++20 versions, and it doesn't actually allow us to know what size the enum is since we're using `unsigned int` as opposed to a fixed-width type. Furthermore, http://wg21.link/p0439 (the paper that made memory_order a scoped enumeration) said: > In order to maintain binary compatibility the underlying type of the scoped enumeration type should be left unspecified, so that implementations can set it to match the underlying type that was previously chosen (either implicitly or explicitly) for the unscoped enumeration type. I think we should just leave it unspecified.
I implemented my proposed fix here: https://reviews.llvm.org/D59029
Should be fixed in r355521.