C++ constexpr constexpr variables


Example

A variable declared constexpr is implicitly const and its value may be used as a constant expression.

Comparison with #define

A constexpr is type-safe replacement for #define based compile-time expressions. With constexpr the compile-time evaluated expression is replaced with the result. For example:

C++11
int main()
{
   constexpr int N = 10 + 2;
   cout << N;
}

will produce the following code:

cout << 12;

A pre-processor based compile-time macro would be different. Consider:

#define N 10 + 2

int main()
{
    cout << N;
}

will produce:

cout << 10 + 2;

which will obviously be converted to cout << 10 + 2;. However, the compiler would have to do more work. Also, it creates a problem if not used correctly.

For example (with #define):

cout << N * 2;

forms:

cout << 10 + 2 * 2; // 14

But a pre-evaluated constexpr would correctly give 24.

Comparison with const

A const variable is a variable which needs memory for its storage. A constexpr does not. A constexpr produces compile time constant, which cannot be changed. You may argue that const may also not be changed. But consider:

int main()
{
   const int size1 = 10;
   const int size2 = abs(10);

   int arr_one[size1]; 
   int arr_two[size2]; 
}

With most compilers the second statement will fail (may work with GCC, for example). The size of any array, as you might know, has to be a constant expression (i.e. results in compile-time value). The second variable size2 is assigned some value that is decided at runtime (even though you know it is 10, for the compiler it is not compile-time).

This means that a const may or may not be a true compile-time constant. You cannot guarantee or enforce that a particular const value is absolutely compile-time. You may use #define but it has its own pitfalls.

Therefore simply use:

C++11
int main()
{
    constexpr int size = 10;

    int arr[size];
}

A constexpr expression must evaluate to a compile-time value. Thus, you cannot use:

C++11
constexpr int size = abs(10);

Unless the function (abs) is itself returning a constexpr.

All basic types can be initialized with constexpr.

C++11
constexpr bool FailFatal = true;
constexpr float PI = 3.14f;
constexpr char* site= "StackOverflow";

Interestingly, and conveniently, you may also use auto:

C++11
constexpr auto domain = ".COM";  // const char * const domain = ".COM"
constexpr auto PI = 3.14;        // constexpr double