Constants

Use Enumerations for Lists of Integral Constants

Reasoning

  • Type safety
  • Grouping misc values together under a single scope.
    • Which can be further improved by using an enum class.
    • Helps ensure no conflicts with other static variables.
  • Openness for specifying an underlying integral type, instead of the default 32-bit int.
  • Avoids hacking via const_cast.
  • Reducing developer overhead by avoiding the redundancy in specifying a type and declaration.

ie:

//Do this:
enum
{
    valueA = 0x0A,
    valueB = 0x0B,
    valueC = 0xFF,
    valueD = 0xF0
};
//Not this:
static const int valueA = 0x0A;
static const int valueB = 0x0B;
static const int valueC = 0xFF;
static const int valueD = 0xF0;
//Nor this:
static constexpr int valueA = 0x0A;
static constexpr int valueB = 0x0B;
static constexpr int valueC = 0xFF;
static constexpr int valueD = 0xF0;
//This is the worst thing you can do. Are these `int`s or `char`s? Unsigned, or not?
#define valueA 0x0A
#define valueB 0x0B
#define valueC 0xFF
#define valueD 0xF0

Private Constants

For internal constants, it is suggested to not name the enum to avoid the extra typing:

class MyClass
{
public:
    MyClass() noexcept { }

private:
    enum
    {
        constantValue = 100,
        otherConstantValue = 0xBEEFCAKE
    };
};

Public Constants

For public constants, it's better to use enum for integrals, or enum class if available to improve the type safety.

class MyClass
{
public:
    enum class SpecialType
    {
        importantTypeName,
        otherImportantTypeName,
        fooTypeName,
        barTypeName
    };

    static constexpr float myVar = 0.0f;
};

Use Namespaces to Encapsulate and Group Constants

Header File Rules

  • Specify an identifier/name to the namespace.
  • Use the enum constants rules for integrals.
  • Use constexpr if available and legal syntax, or const, for other types.
namespace MyGlobalConstants
{
    constexpr float foo = 0.0f;
    constexpr double bar = 100.0;

    enum
    {
        car = 100,
        van = 200,
        truck = 200
    };
}

Implementation File Rules

Similarly to the header file rules, except you haven't the need to name the namespace or enum as the contents are private and tucked away from other files.

namespace
{
    constexpr float foo = 0.0f;
    constexpr double bar = 100.0;

    enum
    {
        car = 100,
        van = 200,
        truck = 200
    };
}