User:D41D8CD98F/constant expression

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.

Definition
For an expression to be a constant expression, it must satisfy the following requirements:

  if the expression is a glvalue:  it must refer to an object with static storage duration or a function;  if it refers to a temporary object that is bound to a reference, the value of the temporary object must satisfy the constraints for prvalues, if applicable (see below);  if the expression is a prvalue:  if the value is an object of class type, each non-static data member of reference type must refer to an entity that satisfies the constraints for glvalues above;  if the value is of pointer type, it must hold one of the following:  address of an object with static storage duration  address past the end of an object with static storage duration  address of a function  a null pointer value <li> if the value is an object of class or array type, each subobject must satisfy these constraints for prvalues;</ul> <li> in either case, the evaluation of the expression, following the rules of the abstract machine, must not evaluate any the following: <ol> <li> the this pointer, except in a function or a  constructor that is being evaluated as part of the expression <li> a function call expression that calls a function (or a constructor) that is not declared constexpr

<li> a function call to a function which is declared, but not defined <li> a function call to a function/constructor template instantiation where the instantiation fails to satisfy constexpr function/constructor requirements <li> an expression that would exceed the implementation-defined limits <li> an expression whose evaluation leads to any form of core language undefined behavior (including signed integer overflow, division by zero, pointer arithmetic outside array bounds, etc). Whether standard library undefined behavior is detected is unspecified.

<li class="t-rev-inl t-rev-inl-noborder t-until-cxx17"> a lambda expression <li> an lvalue-to-rvalue implicit conversion, unless the lvalue... <li> has integral or enumeration type and refers to a complete non-volatile const object, which is initialized with a prvalue constant expression

<li> is a non-volatile glvalue that refers to an element of a string literal <li> has literal type and refers to a non-volatile object defined with or to its non-mutable subobject <li> has literal type and refers to a non-volatile object whose lifetime began within the evaluation of this expression </ol> <li> an lvalue-to-rvalue implicit conversion or modification applied to a non-active member of a union or its subobject (even if it shares a common initial sequence with the active member) <li> an invocation of an implicitly-defined copy/move constructor or copy/move assignment operator for a union whose active member (if any) is mutable, unless the lifetime of the union object began within the evaluation of this expression <li> an assignment expression or invocation of an overloaded assignment operator that would change the active member of a union <li> an referring to a variable or a data member of reference type, unless it was initialized with a glvalue constant expression or its lifetime began within the evaluation of this expression <li> conversion from cv to any pointer-to-object type <li> dynamic_cast <li> reinterpret_cast <li> pseudo-destructor call (note: since destructors cannot be constexpr, explicit destructor call on class type is disallowed by the prohibition on non-constexpr function call) <li class="t-rev-inl t-rev-inl-noborder t-until-cxx14"> an increment or a decrement operator <li class="t-rev-inl t-rev-inl-noborder t-since-cxx14"> modification of an object, unless the object has non-volatile literal type and its lifetime began within the evaluation of the expression

<li> a typeid expression applied to a glvalue of polymorphic type <li> a new-expression or a delete-expression <li class="t-rev-inl t-rev-inl-noborder t-since-cxx20"> a three-way comparison comparing pointers that do not point to the same complete object or to any subobject thereof <li> an equality or relational operator when the result is unspecified <li class="t-rev-inl t-rev-inl-noborder t-until-cxx14"> an assignment or a compound assignment operator <li> a throw expression </ol> </ul>

Note that in a lambda-expression, if a reference to or to a variable defined outside that lambda would be an odr-use, the reference is transformed into an use of the corresponding data member of the closure. Such use is subject to the constraint on evaluation of.

Integral 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. If an expression of class type is used where an integral constant expression is expected, the expression is contextually implicitly converted to an integral or unscoped enumeration type.
 * only integral constant expressions can be used as, bit-field lengths, enumeration initializers when the underlying type is not fixed, , and alignments.

Converted constant expression
A converted constant expression of type is an expression implicitly converted to type, where the converted expression is a constant expression, and the implicit conversion sequence contains only:
 * constexpr user-defined conversions (so a class can be used where integral type is expected)
 * lvalue-to-rvalue conversions
 * integral promotions
 * non-narrowing integral conversions


 * And if any reference binding takes place, it is direct binding (not one that constructs a temporary object)
 * Only converted constant expressions can be used as case expressions, enumerator initializers when the underlying type is fixed,, and as non-type template arguments.

A contextually converted constant expression of type  is an expression, contextually converted to, where the converted expression is a constant expression and the conversion sequence contains only the conversions above. Such expressions can be used in specifications and static assert declarations.