xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/modernize/macro-to-enum.rst (revision 6e566bc5523f743bc34a7e26f050f1f2b4d699a8)
1.. title:: clang-tidy - modernize-macro-to-enum
2
3modernize-macro-to-enum
4=======================
5
6Replaces groups of adjacent macros with an unscoped anonymous enum.
7Using an unscoped anonymous enum ensures that everywhere the macro
8token was used previously, the enumerator name may be safely used.
9
10This check can be used to enforce the C++ core guideline `Enum.1:
11Prefer enumerations over macros
12<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#enum1-prefer-enumerations-over-macros>`_,
13within the constraints outlined below.
14
15Potential macros for replacement must meet the following constraints:
16
17- Macros must expand only to integral literal tokens or expressions
18  of literal tokens.  The expression may contain any of the unary
19  operators ``-``, ``+``, ``~`` or ``!``, any of the binary operators
20  ``,``, ``-``, ``+``, ``*``, ``/``, ``%``, ``&``, ``|``, ``^``, ``<``,
21  ``>``, ``<=``, ``>=``, ``==``, ``!=``, ``||``, ``&&``, ``<<``, ``>>``
22  or ``<=>``, the ternary operator ``?:`` and its
23  `GNU extension <https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html>`_.
24  Parenthesized expressions are also recognized.  This recognizes
25  most valid expressions.  In particular, expressions with the
26  ``sizeof`` operator are not recognized.
27- Macros must be defined on sequential source file lines, or with
28  only comment lines in between macro definitions.
29- Macros must all be defined in the same source file.
30- Macros must not be defined within a conditional compilation block.
31  (Conditional include guards are exempt from this constraint.)
32- Macros must not be defined adjacent to other preprocessor directives.
33- Macros must not be used in any conditional preprocessing directive.
34- Macros must not be used as arguments to other macros.
35- Macros must not be undefined.
36- Macros must be defined at the top-level, not inside any declaration or
37  definition.
38
39Each cluster of macros meeting the above constraints is presumed to
40be a set of values suitable for replacement by an anonymous enum.
41From there, a developer can give the anonymous enum a name and
42continue refactoring to a scoped enum if desired.  Comments on the
43same line as a macro definition or between subsequent macro definitions
44are preserved in the output.  No formatting is assumed in the provided
45replacements, although clang-tidy can optionally format all fixes.
46
47.. warning::
48
49  Initializing expressions are assumed to be valid initializers for
50  an enum.  C requires that enum values fit into an ``int``, but
51  this may not be the case for some accepted constant expressions.
52  For instance ``1 << 40`` will not fit into an ``int`` when the size of
53  an ``int`` is 32 bits.
54
55Examples:
56
57.. code-block:: c++
58
59  #define RED   0xFF0000
60  #define GREEN 0x00FF00
61  #define BLUE  0x0000FF
62
63  #define TM_NONE (-1) // No method selected.
64  #define TM_ONE 1    // Use tailored method one.
65  #define TM_TWO 2    // Use tailored method two.  Method two
66                      // is preferable to method one.
67  #define TM_THREE 3  // Use tailored method three.
68
69becomes
70
71.. code-block:: c++
72
73  enum {
74  RED = 0xFF0000,
75  GREEN = 0x00FF00,
76  BLUE = 0x0000FF
77  };
78
79  enum {
80  TM_NONE = (-1), // No method selected.
81  TM_ONE = 1,    // Use tailored method one.
82  TM_TWO = 2,    // Use tailored method two.  Method two
83                      // is preferable to method one.
84  TM_THREE = 3  // Use tailored method three.
85  };
86