On Friday, June 20, 2014 9:42:38 PM UTC-7, David Krauss wrote:
>
> Promotions are still observable even without std::underlying_type. C++ since C++98 specifies that an (unscoped) enumeration value implicitly converts to the lowest-rank promoted integer type that can represent all the enumerators (§4.5/2 or 3), regardless of the underlying type (which already existed in C++98 §7.2/5). C makes the converted-to type implementation-defined, not unlike the C++ underlying type. This can be directly observed as of C11 using a type-generic expression and the unary + operator.
>
> Making the underlying type identical to the C++ implicit promotion conversion type is a very reasonable policy, but for whatever reason, Microsoft did not choose to do so.
>
> Essentially your proposal comes down to requiring MSVC to change its semantics to hide this blunder. Since the impact on users is the same, it might be more fruitful to complain directly to Microsoft, and see if they can change their underlying types, at least as far as std::underlying_type goes if not the ABI.
>
> Unscoped enumerations are unpredictable like that.
>
Sorry; I'm a bit confused here.
I thought that "signed int" was "the lowest rank promoted integer type that can represent all the enumerators", given that the only enumerator is 0. In Microsoft's compiler, the promoted type is "signed int" and the underlying_type is "signed int", so wouldn't that mean that they are already following "a very reasonable policy" of keeping the two types identical?
It's GCC and clang that are setting the promoted type and underlying type to different things.
>
> Enumerations are not aliasing-compatible with their underlying types (although wide character types are), so you can’t use such a union directly nor the equivalent reinterpret_cast. This has been brought up in undefined behavior discussions. Anyway, I wasn’t talking about bitwise representations.
The compilers in widespread use all allow type punning through a union, because the true, official constraint in the Standard - that memcpy() is the only way out - is far too much of an impediment to getting work done and to machine performance.
(A might_alias statement would be really useful in C/C++. Declare that some number of pointers and/or references may point to the same elements even if their types are unrelated.)
Melissa