|
1 | 1 | # <a name="main"></a>C++ Core Guidelines
|
2 | 2 |
|
3 |
| -july 16, 2016 |
| 3 | +July 16, 2016 |
4 | 4 |
|
5 | 5 | Editors:
|
6 | 6 |
|
@@ -7018,15 +7018,16 @@ Enumerations are used to define sets of integer values and for defining types fo
|
7018 | 7018 |
|
7019 | 7019 | Enumeration rule summary:
|
7020 | 7020 |
|
7021 |
| -* [Enum.1: Prefer enums over macros](#Renum-macro) |
7022 |
| -* [Enum.2: Use enumerations to represent sets of named constants](#Renum-set) |
7023 |
| -* [Enum.3: Prefer class enums over "plain" enums](#Renum-class) |
| 7021 | +* [Enum.1: Prefer enumerations over macros](#Renum-macro) |
| 7022 | +* [Enum.2: Use enumerations to represent sets of related named constants](#Renum-set) |
| 7023 | +* [Enum.3: Prefer `enum class`es over "plain" `enum`s](#Renum-class) |
7024 | 7024 | * [Enum.4: Define operations on enumerations for safe and simple use](#Renum-oper)
|
7025 | 7025 | * [Enum.5: Don't use `ALL_CAPS` for enumerators](#Renum-caps)
|
7026 |
| -* [Enum.6: Use unnamed enumerations for ???](#Renum-unnamed) |
7027 |
| -* ??? |
| 7026 | +* [Enum.6: Avoid unnamed enumerations](#Renum-unnamed) |
| 7027 | +* [Enum.7: Specify the underlying type of an enumeration only when necessary](#Renum-underlying) |
| 7028 | +* [Enum.8: Specify enumerator values only when necessary](#Renum-value) |
7028 | 7029 |
|
7029 |
| -### <a name="Renum-macro"></a>Enum.1: Prefer enums over macros |
| 7030 | +### <a name="Renum-macro"></a>Enum.1: Prefer enumerations over macros |
7030 | 7031 |
|
7031 | 7032 | ##### Reason
|
7032 | 7033 |
|
@@ -7057,23 +7058,47 @@ Instead use an `enum`:
|
7057 | 7058 | int webby = blue; // error: be specific
|
7058 | 7059 | Webcolor webby = Webcolor::blue;
|
7059 | 7060 |
|
| 7061 | +We used an `enum class` to avoid name clashes. |
| 7062 | + |
7060 | 7063 | ##### Enforcement
|
7061 | 7064 |
|
7062 |
| -Flag macros that define integer values |
| 7065 | +Flag macros that define integer values. |
| 7066 | + |
7063 | 7067 |
|
7064 |
| -### <a name="Renum-set"></a>Enum.2: Use enumerations to represent sets of named constants |
| 7068 | +### <a name="Renum-set"></a>Enum.2: Use enumerations to represent sets of related named constants |
7065 | 7069 |
|
7066 | 7070 | ##### Reason
|
7067 | 7071 |
|
7068 |
| -An enumeration shows the enumerators to be related and can be a named type |
| 7072 | +An enumeration shows the enumerators to be related and can be a named type. |
| 7073 | + |
| 7074 | + |
7069 | 7075 |
|
7070 | 7076 | ##### Example
|
7071 | 7077 |
|
7072 | 7078 | enum class Webcolor { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF };
|
7073 | 7079 |
|
| 7080 | + |
| 7081 | +##### Note |
| 7082 | + |
| 7083 | +Switching on an enumeration is common and the compiler can warn against unusual patterns of case labels. For example: |
| 7084 | + |
| 7085 | + enum class Productinfo { red = 0, purple = 1, blue = 2 }; |
| 7086 | + |
| 7087 | + void print(Productinfo inf) |
| 7088 | + { |
| 7089 | + switch (inf) { |
| 7090 | + case Productinfo::red: cout << "red"; break; |
| 7091 | + case Productinfo::purple: cout << "purple"; break; |
| 7092 | + } |
| 7093 | + } |
| 7094 | + |
| 7095 | +Such off-by-one switch`statements are often the results of an added enumerator and insufficient testing. |
| 7096 | + |
7074 | 7097 | ##### Enforcement
|
7075 | 7098 |
|
7076 |
| -??? |
| 7099 | +* Flag `switch`-statements where the `case`s cover most but not all enumerators of an enumeration. |
| 7100 | +* Flag `switch`-statements where the `case`s cover a few enumerators of an enumeration, but has no `default`. |
| 7101 | + |
7077 | 7102 |
|
7078 | 7103 | ### <a name="Renum-class"></a>Enum.3: Prefer class enums over "plain" enums
|
7079 | 7104 |
|
@@ -7117,39 +7142,123 @@ Convenience of use and avoidance of errors.
|
7117 | 7142 |
|
7118 | 7143 | ##### Example
|
7119 | 7144 |
|
7120 |
| - ??? |
| 7145 | + enum Day { mon, tue, wed, thu, fri, sat, sun }; |
| 7146 | + |
| 7147 | + Day operator++(Day& d) |
| 7148 | + { |
| 7149 | + return d==sun?mon:Day{++d}; |
| 7150 | + } |
| 7151 | + |
| 7152 | + Day today = sat; |
| 7153 | + Day tomorrow = ++today; |
7121 | 7154 |
|
7122 | 7155 | ##### Enforcement
|
7123 | 7156 |
|
7124 |
| -??? |
| 7157 | +Flag repeated experssions cast back into a an enumeration. |
| 7158 | + |
7125 | 7159 |
|
7126 | 7160 | ### <a name="Renum-caps"></a>Enum.5: Don't use `ALL_CAPS` for enumerators
|
7127 | 7161 |
|
7128 | 7162 | ##### Reason
|
7129 | 7163 |
|
7130 | 7164 | Avoid clashes with macros.
|
7131 | 7165 |
|
| 7166 | +##### Example, bad |
| 7167 | + |
| 7168 | + // webcolors.h (third party header) |
| 7169 | + #define RED 0xFF0000 |
| 7170 | + #define GREEN 0x00FF00 |
| 7171 | + #define BLUE 0x0000FF |
| 7172 | + |
| 7173 | + // productinfo.h |
| 7174 | + // The following define product subtypes based on color |
| 7175 | + |
| 7176 | + enum class Productinfo { RED, PURPLE, BLUE }; // syntax error |
| 7177 | + |
| 7178 | +##### Enforcement |
| 7179 | + |
| 7180 | +Flag ALL_CAPS ennumerators. |
| 7181 | + |
| 7182 | +### <a name="Renum-unnamed"></a>Enum.6: Avoid unnamed enumerations |
| 7183 | + |
| 7184 | +##### Reason |
| 7185 | + |
| 7186 | +If you can't name an enumeration, the values are not related |
| 7187 | + |
| 7188 | +##### Example, bad |
| 7189 | + |
| 7190 | + enum { red = 0x,FF0000, scale = 4, signed = 1 }; |
| 7191 | + |
| 7192 | +Such code is not uncommon in code written before there were convenient alternative ways of specifying integer constants. |
| 7193 | + |
| 7194 | +##### Alternative |
| 7195 | + |
| 7196 | +Use `constexpr` values instead. For example: |
| 7197 | + |
| 7198 | + constexpr int red = 0x,FF0000; |
| 7199 | + constexpr short scale = 4; |
| 7200 | + constexpr bool signed = true; |
| 7201 | + |
| 7202 | +##### Enforcement |
| 7203 | + |
| 7204 | +Flag unnamed enumerations. |
| 7205 | + |
| 7206 | + |
| 7207 | +### <a name="Renum-underlying"></a>Enum.7: Specify the underlying type of an enumeration only when necessary |
| 7208 | + |
| 7209 | +##### Reason |
| 7210 | + |
| 7211 | +The default is the easiest to read and write. |
| 7212 | +`int` is the default integer type. |
| 7213 | +`int` is compatible with C `enum`s. |
| 7214 | + |
7132 | 7215 | ##### Example
|
7133 | 7216 |
|
7134 |
| - ??? |
| 7217 | + enum class Direction : char { n,s,e,w, ne, nw, se, sw }; // underlying type saves space |
| 7218 | + |
| 7219 | + enum class Webcolor : int { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF }; // underlying type is redundant |
| 7220 | + |
| 7221 | +##### Note |
| 7222 | + |
| 7223 | +Specifying the underlying type is necessary in forward declations of enumerations: |
| 7224 | + |
| 7225 | + enum Flags : char; |
| 7226 | + |
| 7227 | + void f(Flags); |
| 7228 | + |
| 7229 | + // .... |
| 7230 | + |
| 7231 | + enum flags : char { /* ... */ }; |
| 7232 | + |
7135 | 7233 |
|
7136 | 7234 | ##### Enforcement
|
7137 | 7235 |
|
7138 |
| -??? |
| 7236 | +???? |
7139 | 7237 |
|
7140 |
| -### <a name="Renum-unnamed"></a>Enum.6: Use unnamed enumerations for ??? |
| 7238 | + |
| 7239 | +### <a name="Renum-value"></a>Enum.8: Specify enumerator values only when necessary |
7141 | 7240 |
|
7142 | 7241 | ##### Reason
|
7143 | 7242 |
|
7144 |
| -??? |
| 7243 | +It's the simplest. |
| 7244 | +It avoids duplicate enumerator values. |
| 7245 | +The default gives a consequtive set of values that is good for `switch`-statement implementations. |
7145 | 7246 |
|
7146 | 7247 | ##### Example
|
7147 | 7248 |
|
7148 |
| - ??? |
| 7249 | + enum class Col1 { red, yellow, blue }; |
| 7250 | + enum class Col2 { red=1, red=2, blue=2 }; // typo |
| 7251 | + enum class Month { jan=1, feb, mar, apr, mar, jun, jul, august, sep, oct, nov, dec }; // starting with 1 is conventional |
| 7252 | + enum class Base_flag { dec=1, oct=dec<<1, hex=dec<<2 }; // set of bits |
| 7253 | + |
| 7254 | +Specifying values are neccessary to match conventional values (e.g., `Month`) |
| 7255 | +and where consecutive values are undesirable (e.g., to get separate bits as in `Base_flag`). |
7149 | 7256 |
|
7150 | 7257 | ##### Enforcement
|
7151 | 7258 |
|
7152 |
| -??? |
| 7259 | +* Flag duplicate enumerator values |
| 7260 | +* flag explicitly specified all-consequtive enumerator values |
| 7261 | + |
7153 | 7262 |
|
7154 | 7263 | # <a name="S-resource"></a>R: Resource management
|
7155 | 7264 |
|
|
0 commit comments