Skip to content

Commit ae8c320

Browse files
Update and extension of enumeration section
1 parent 39eaac7 commit ae8c320

File tree

1 file changed

+128
-19
lines changed

1 file changed

+128
-19
lines changed

CppCoreGuidelines.md

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# <a name="main"></a>C++ Core Guidelines
22

3-
july 16, 2016
3+
July 16, 2016
44

55
Editors:
66

@@ -7018,15 +7018,16 @@ Enumerations are used to define sets of integer values and for defining types fo
70187018

70197019
Enumeration rule summary:
70207020

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)
70247024
* [Enum.4: Define operations on enumerations for safe and simple use](#Renum-oper)
70257025
* [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)
70287029

7029-
### <a name="Renum-macro"></a>Enum.1: Prefer enums over macros
7030+
### <a name="Renum-macro"></a>Enum.1: Prefer enumerations over macros
70307031

70317032
##### Reason
70327033

@@ -7057,23 +7058,47 @@ Instead use an `enum`:
70577058
int webby = blue; // error: be specific
70587059
Webcolor webby = Webcolor::blue;
70597060

7061+
We used an `enum class` to avoid name clashes.
7062+
70607063
##### Enforcement
70617064

7062-
Flag macros that define integer values
7065+
Flag macros that define integer values.
7066+
70637067

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
70657069

70667070
##### Reason
70677071

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+
70697075

70707076
##### Example
70717077

70727078
enum class Webcolor { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF };
70737079

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+
70747097
##### Enforcement
70757098

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+
70777102

70787103
### <a name="Renum-class"></a>Enum.3: Prefer class enums over "plain" enums
70797104

@@ -7117,39 +7142,123 @@ Convenience of use and avoidance of errors.
71177142

71187143
##### Example
71197144

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;
71217154

71227155
##### Enforcement
71237156

7124-
???
7157+
Flag repeated experssions cast back into a an enumeration.
7158+
71257159

71267160
### <a name="Renum-caps"></a>Enum.5: Don't use `ALL_CAPS` for enumerators
71277161

71287162
##### Reason
71297163

71307164
Avoid clashes with macros.
71317165

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+
71327215
##### Example
71337216

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+
71357233

71367234
##### Enforcement
71377235

7138-
???
7236+
????
71397237

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
71417240

71427241
##### Reason
71437242

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.
71457246

71467247
##### Example
71477248

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`).
71497256

71507257
##### Enforcement
71517258

7152-
???
7259+
* Flag duplicate enumerator values
7260+
* flag explicitly specified all-consequtive enumerator values
7261+
71537262

71547263
# <a name="S-resource"></a>R: Resource management
71557264

0 commit comments

Comments
 (0)