##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# Constant expressions

From cppreference.com
< cpp‎ | language

Defines an expression that can be evaluated at compile time.

Such expressions can be used as non-type template arguments, array sizes, and in other contexts that require constant expressions, e.g.

    int n = 1;
    std::array<int, n> a1; // error, n is not a constant expression
    const int cn = 2;
    std::array<int, cn> a2; // OK, cn is a constant expression

### [edit] Core constant expressions

A core constant expression is any expression that does not have any one of the following in any subexpression (ignoring the unevaluated arguments of &&, ||, and ?:)

1) A function call expression that calls a function (or a constructor) that is not declared constexpr

    constexpr int n = std::numeric_limits<int>::max(); // OK, max() is constexpr
    constexpr int m = std::time(NULL); // Error: std::time() is not constexpr

2) A function call to a `constexpr` function which is declared, but not defined, if the function call itself is not made inside the body of a `constexpr` function.
3) A function call to a `constexpr` function with arguments that do not produce a constant expression when substituted

    constexpr const int* addr(const int& ir) { return &ir; }
    static const int x = 5;
    constexpr const int* xp = addr(x); // OK
    constexpr const int* tp = addr(5); // error: &5 is not a constant expression

4) A function call to a `constexpr` function with arguments that do not produce constant expressions in member-initializer lists that are called from this function

    int x;
    struct A {
        constexpr A(bool b) : m(b?42:x) { }
        int m;
    };
    constexpr int v = A(true).m; // OK
    constexpr int w = A(false).m; // error: non-const x

5) A function call to a recursive `constexpr` function that would exceed compile-time recursion depth limit (implementation-defined)
6) The this pointer except if used for class member access inside a non-static member function.

7) An expression whose result is not mathematically defined or is out of range for its type.
    constexpr double d1 = 2.0/1.0; // OK
    constexpr double d2 = 2.0/0.0; // Error: not defined
    constexpr int n = std::numeric_limits<int>::max() + 1; // Error: overflow
| (until C++14)
7) An expression whose evaluation leads to any form of undefined behavior (including signed integer overflow, division by zero, pointer arithmetic outside array bounds, etc) | (since C++14)

8) A lambda expression
9) An lvalue-to-rvalue implicit conversion applied to a non-active member of a union or its subobject
10) Any other lvalue-to-rvalue implicit conversion, unless the lvalue...
a) has integral or enumeration type, is non-volatile const, and is initialized with a constant expression, or an array of such (including a string literal)
b) has literal type and refers to a non-volatile object defined with `constexpr` or to its non-mutable subobject
c) has literal type and refers to a non-volatile temporary, initialized with a constant expression
11) a reference to a variable unless it was initialized with a constant expression or is a non-static data member of a temporary object whose lifetime begain within this expression

12) conversion from cv void* to any pointer-to-object type | (since C++14)

13) dynamic_cast
14) reinterpret_cast
15) pseudo-destructor call
16) an increment or a decrement operator
17) a typeid expression applied to a glvalue of polymorphic type
18) a new-expression or a delete-expression
19) a subtraction operator between two pointers
20) an equality or relational operator when the result is unspecified
21) an assignment or a compount assignment operator
22) a throw expression

| This section is incomplete Reason: needs more mini-examples and less standardese

### [edit] Constant expression

- Integral constant expression is an expression of integral or unscoped enumeration type implicitly converted to a prvalue, where the converted expression is a core constant expression.

  only integral constant expressions can be used as bit-field lengths, enumeration initializers when the underlying type is not fixed, null-pointer constants, and alignments

- Converted constant expression is an expression implicitly converted to prvalye of type T, where the converted expression is a core constant expression. If the literal constant expression has class type, it is contextually implicitly converted to the expected integral or unscoped enumeration type with a `constexpr` user-defined conversion function.

  only converted constant expressions can be used as case expressions, enumerator initializers when the underlying type is fixed, array bounds, the dimensions in new-expressions other than the first, and as integral and enumeration non-type template arguments

- Literal constant expression is a prvalue core constant expression of non-pointer literal type (after conversions as required by context). A literal constant expression of array or class type requires that each subobject is initialized with a constant expression.
- Reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function
- Address constant expression is a prvalue core constant expression (after conversions required by context) of type std::nullptr_t or of a pointer type, which points to an object with static storage duration, one past the end of an array with static storage duration, to a function, or is a null pointer.

### [edit] Notes

Implementations are not permitted to declare library functions as `constexpr` unless the standard says the function is `constexpr` | (since C++14)

| This section is incomplete Reason: examples

### [edit] See also

- constexpr specifier
- std::is_literal_type

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/constant_expression&oldid=72460"
Category:

- Todo with reason