Namespaces
Variants
Views
Actions

Constant expressions

From cppreference.com
< cpp‎ | language
Revision as of 19:52, 17 March 2014 by Cubbi (Talk | contribs)

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

Contents

Core constant expressions

A core constant expression is any expression that does not have any one of the following in any subexpression (except that arguments of &&, ||, and ?: that aren't evaluated are not considered)

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
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
b) has literal type and refers to an object defined with a constant expression (or to its subobject)
c) has literal type and refers to a non-volatile temporary, initialized with constant expression
11) a reference to a variable unless it was initialized with a constant expression
14) pseudo-destructor call
15) an increment or a decrement operator
16) a typeid expression applied to a polymorphic type
17) a new-expression or a delete-expression
18) a subtraction operator between two pointers
19) an equality or relational operator when the result is unspecified
20) an assignment or a compount assignment operator
21) a throw expression

Special constant expression

  • Literal constant expression is a prvalue core constant expression of non-pointer literal type
  • Integral constant expression is a literal constant expression of integral or unscoped enumeration type
only integral constant expressions can be used as array bounds, bit-field lengths, enumeration initializers when the underlying type is not fixed, null-pointer constants, and alignments
  • Converted constant expression is a literal constant expression implicitly converted to type T, where the implicit conversion is permitted in a literal constant expression
only converted constant expressions can be used as case expressions, enumerator initializers when the underlying type is fixed, and as integral and enumeration non-type template arguments
  • 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 of type std::nullptr_t or of a pointer type, which points to an object with static storage duration, to a function, or is a null pointer.

Notes

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

See also