constexpr functions

suggest change

A function that is declared constexpr is implicitly inline and calls to such a function potentially yield constant expressions. For example, the following function, if called with constant expression arguments, yields a constant expression too:

constexpr int Sum(int a, int b)
{
    return a + b;
}

Thus, the result of the function call may be used as an array bound or a template argument, or to initialize a constexpr variable:

int main()
{
    constexpr int S = Sum(10,20);
   
    int Array[S];
    int Array2[Sum(20,30)]; // 50 array size, compile time
}

Note that if you remove constexpr from function’s return type specification, assignment to S will not work, as S is a constexpr variable, and must be assigned a compile-time const. Similarly, size of array will also not be a constant-expression, if function Sum is not constexpr.

Interesting thing about constexpr functions is that you may also use it like ordinary functions:

int a = 20;
auto sum = Sum(a, abs(-20));

Sum will not be a constexpr function now, it will be compiled as an ordinary function, taking variable (non-constant) arguments, and returning non-constant value. You need not to write two functions.

It also means that if you try to assign such call to a non-const variable, it won’t compile:

int a = 20;
constexpr auto sum = Sum(a, abs(-20));

The reason is simple: constexpr must only be assigned a compile-time constant. However, the above function call makes Sum a non-constexpr (R-value is non-const, but L-value is declaring itself to be constexpr).


The constexpr function must also return a compile-time constant. Following will not compile:

constexpr int Sum(int a, int b)
{
    int a1 = a;     // ERROR
    return a + b;
}

Because a1 is a non-constexpr variable, and prohibits the function from being a true constexpr function. Making it constexpr and assigning it a will also not work - since value of a (incoming parameter) is still not yet known:

constexpr int Sum(int a, int b)
{
   constexpr int a1 = a;     // ERROR
   ..

Furthermore, following will also not compile:

constexpr int Sum(int a, int b)
{
   return abs(a) + b; // or abs(a) + abs(b)
}

Since abs(a) is not a constant expression (even abs(10) will not work, since abs is not returning a constexpr int !

What about this?

constexpr int Abs(int v)
{
    return v >= 0 ? v : -v;
}

constexpr int Sum(int a, int b)
{
    return Abs(a) + b;
}

We crafted our own Abs function which is a constexpr, and the body of Abs also doesn’t break any rule. Also, at the call site (inside Sum), the expression evaluates to a constexpr. Hence, the call to Sum(-10, 20) will be a compile-time constant expression resulting to 30.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


constexpr:
* constexpr functions

Table Of Contents
8 Arrays
11 Loops
39 Streams
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
84 RTTI
87 Scopes
90 constexpr
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype