Talk:cpp/language/enum
78.128.11.39 02:57, 24 April 2015 (PDT) This page refers to `type-specifier-seq`, but the definition of this term is nowhere to be found here? -- Kiril
- it says "type-specifier-seq of the declaration syntax". Declaration is the link to follow that explains the syntax and its components. --Cubbi (talk) 03:20, 24 April 2015 (PDT)
Contents |
[edit] Incorrect description of underlying type for enums without a fixed underlying type
> Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is either int or, if not all enumerator values can be represented as int, an implementation-defined larger integral type that can represent all enumerator values.
The correct rule is here: http://eel.is/c++draft/dcl.enum#7
Note that, when the enumerators are small, the underlying type "shall not be larger than int", *not* "is int". In particular, most non-MSVC compilers, the underlying type will be *unsigned* if there are no negative enumerators; GCC and Clang also provide -fshort-enums which will select types smaller than int if the enumerators fit in a smaller type.
-- zygoloid 13:28, 30 June 2017 (PDT)
[edit] Enum iteration
What is a convenient way to iterate all values of a enum type?
146.247.191.6 05:56, 15 July 2017 (PDT)
[edit] Incorrect pre-C++ 11 example?
In the first description of an enum definition, it says that the optional enum-base existed already before C++ 11. In the text below it says that the enum base was introduced with C++ 11. Also, with an old g++ without the C++ standard flag, this gives compiler errors. So, in short: The "enum-base (optional)" should be removed from the first definition, right? Gemini67 (talk) 02:10, 25 September 2017 (PDT)
[edit] int -> Enum conversion vs initialization
There seems to be a contradiction here. The following passage describes how the range of an enum defines valid int->enum conversions:
- Values of integer, floating-point, and other enumeration types can be converted, such as by static_cast, to any enumeration type. The result is unspecified (until C++17)undefined behavior (since C++17) if the value, converted to the enumeration's underlying type, is out of this enumeration's range
Later in the page there is a code example which appears to do exactly this conversion. The section which describes how enums whose “underlying type is fixed can be initialized from an integer without a cast” contains the code byte b { 42 };
.
The difference between conversion and initialization here is subtle enough and probably deserves some further explanation (at least in the section quoted above it would be good to explicitly state that the conformant list-init does not trigger UB).
Also possibly worth stating that at a practical level it is possible for an enum to assume any value representable by the underlying type - if it is list initialized appropriately.
Randomphrase (talk) 04:17, 26 September 2017 (PDT)
- since it became undefined behavior, any "practical level" considerations go out the window. Not quite following the byte example though - as you say, it's not conversion, and in fact won't compile when it's out of range. --Cubbi (talk) 08:59, 26 September 2017 (PDT)
- No, list initialization in this manner is NOT UB - so practical considerations DO apply. And my point being that saying “types can be converted, such as by static_cast” it leaves open the question whether list initialization counts as such a conversion. Turns out it does not, but this is not obvious. Use of a constructor to turn one type into another is commonly called conversion construction, and the term is often applied when instantiating primitive types as well. This usage may be incorrect (I’m not sure) but that is even more reason to clarify the intent here. —Randomphrase (talk) 04:11, 28 September 2017 (PDT)
- Ok, the paragraph you quoted made be believe you were talking about undefined behavior on conversion from integer to enum outside its range. What conversions are is described with some detail in the pages under cpp/language/expressions#Conversions (yes, some of them call converting constructors), and if you were to quote byte{42} from the byte example, that would be an example of a conversion. It's not (and can't be) out of range, though. --Cubbi (talk) 08:32, 28 September 2017 (PDT)
- No, list initialization in this manner is NOT UB - so practical considerations DO apply. And my point being that saying “types can be converted, such as by static_cast” it leaves open the question whether list initialization counts as such a conversion. Turns out it does not, but this is not obvious. Use of a constructor to turn one type into another is commonly called conversion construction, and the term is often applied when instantiating primitive types as well. This usage may be incorrect (I’m not sure) but that is even more reason to clarify the intent here. —Randomphrase (talk) 04:11, 28 September 2017 (PDT)
[edit] ABIs expressly designed to penalize passing/returning structures by value
Why would someone design an ABI "expressly" to penalize passing structures by value? I would think that any penalization that happens is a side effect of the implementation, not a specific design goal. 2620:0:1000:8010:E638:F5D7:307C:4C99 11:18, 8 March 2018 (PST)
- that wording was copied from the proposal that introduced that bit of C++17, p0138r2 - perhaps the author had someone in mind, but indeed we could rephrase it. --Cubbi (talk) 11:30, 8 March 2018 (PST)
[edit] Could do with a link to and example of underlying_type
E.g.
std::ostream& operator<<(std::ostream& os, altitude al) { return os << static_cast<std::underlying_type<altitude>::type>(al); }
213.125.253.236 05:03, 20 September 2019 (PDT)