Skip to content

Modern C++ • Relaxed constexpr functions

C++11 introduced a more generalized framework to write constant expressions, extending to regular functions and user-defined objects. This removed many of the limitations in previous versions but still there were limits on the structure of a function in order for it to be suitable to become constexpr.

One of the biggest limitations was the fact that constant-expression functions could only have a body consisting of a single return <expr> statement, where <expr> is a constant expression itself, and a very limited syntax. This was (is) necessary in order to avoid side effects outside of the function that could lead to errors or inefficiencies, such as memory allocations/deallocations, templating, exceptions, lambdas, etc. For example, the following constexpr functions are illegal in C++11

constexpr int f(int x)   // error: x=(x+1) not a const-expression
{
    return x++;
}
 
constexpr int f2(int x)  // error: body of f2() not a return statement
{
    int y = 5;
    return x+y;
}
 
constexpr int f3(int x)  // error: body of f3() not a return statement
{
    if(x>0)
       return 5;
    else
       return 0;
}
 
constexpr int f4(int x)  // error: body of f4() not a return statement
{
    for(int i=0; i<5; i++){
        x = i * i + x;
    }
    return x;
}

C++14 has relaxed these constraints so that it is now possible to use a richer syntax. Specifically, local variables, if statements and loops are now allowed. The above code compiles now perfectly in C++14

int y = f(1);    // =1
int y2 = f2(1);  // =6
int y3 = f3(1);  // =5
int y4 = f4(1);  // =31

Great!

Published inModern C++