Missing constexpr specifier

constexpr specifier can used on expression for compile-time evaluation

Description

This defect occurs if you omit the constexpr specifier when a variable is initialized by using an expression that can be evaluated at compile time.

The defect checker flags a local variable definition without the constexpr specifier if the variable is initialized with one of the following and not modified subsequently in the code:

  • A compile-time constant, for instance, a literal value.

  • An expression involving compile-time constants only.

  • Calls to a function with compile-time constants as parameters, provided the function is itself constexpr or the function contains only a return statement involving its parameters.

  • A constructor call with a compile-time constant, provided all member functions of the class including the constructor are themselves constexpr.

The checker does not flag local, static variables.

Risk

If a variable value is computed from an expression that involves compile-time constants only, using constexpr before the variable definition, like this:

constexpr double eValSquared = 2.718*2.718;
ensures that the expression is evaluated at compile time. The compile-time evaluation saves on run-time overheads. Sometimes, the performance gains at run time can be significant.

If the expression cannot be evaluated at compile time, the constexpr keyword ensures that you get a compilation error. You can then fix the underlying issue if possible.

Note that the const keyword does not guarantee compile-time evaluation. The const keyword simply forbids direct modification of the variable value after initialization. Depending on how the variable is initialized, the initialization can happen at compile time or run time.

Fix

Add the constexpr specifier to the variable definition.

Performance improvements might vary based on the compiler, library implementation, and environment that you are using.

Examples

expand all

double squareIfPositive(double val) {
    return val > 0? (val * val): 0;
}

void initialize(void) {
    double eVal = 2.718; 
    double eValSquare = squareIfPositive(2.718);
    const double eValCubed = 2.718 * 2.718 * 2.718;
}

In this example, the checker flags the three variable definitions in the initialize function because the variables are initialized with expressions involving literal values and the constexpr keyword is omitted.

Correction – Add constexpr Specifier
constexpr double squareIfPositive(double val) {
    return val > 0? (val * val): 0;
}

void initialize(void) {
    constexpr double eVal = 2.718; 
    constexpr double eValSquare = squareIfPositive(2.718);
    constexpr double eValCubed = 2.718 * 2.718 * 2.718;
}

Add the constexpr specifier to the variable definitions. To avoid compile-time errors, make sure that the function squareIfPositive, which returns a value to a constexpr variable, is itself constexpr.

Result Information

Group: Performance
Language: C++
Default: Off
Command-Line Syntax: MISSING_CONSTEXPR
Impact: Medium
Introduced in R2020b