Стандарт C++ 11 (1119564), страница 43
Текст из файла (страница 43)
— end note ]constant-expression:conditional-expression2A conditional-expression is a core constant expression unless it involves one of the following as a potentiallyevaluated subexpression (3.2), but subexpressions of logical AND (5.14), logical OR (5.15), and conditional (5.16) operations that are not evaluated are not considered [ Note: An overloaded operator invokes afunction. — end note ]:— this (5.1) unless it appears as the postfix-expression in a class member access expression, includingthe result of the implicit transformation in the body of a non-static member function (9.3.1);— an invocation of a function other than a constexpr constructor for a literal class or a constexprfunction [ Note: Overload resolution (13.3) is applied as usual — end note ];— an invocation of an undefined constexpr function or an undefined constexpr constructor outside thedefinition of a constexpr function or a constexpr constructor;— an invocation of a constexpr function with arguments that, when substituted by function invocationsubstitution (7.1.5), do not produce a constant expression; [ Example:constexpr const int* addr(const int& ir) { return &ir; } // OKstatic const int x = 5;constexpr const int* xp = addr(x); // OK: (const int*)&(const int&)x is an// address contant expressionconstexpr const int* tp = addr(5); // error, initializer for constexpr variable not a constant// expression; (const int*)&(const int&)5 is not a constant// expression because it takes the address of a temporary83) However, an invocation of an overloaded comma operator is an ordinary function call; hence, the evaluations of its argumentexpressions are unsequenced relative to one another (see 1.9).§ 5.19© ISO/IEC 2011 – All rights reserved127ISO/IEC 14882:2011(E)— end example ]— an invocation of a constexpr constructor with arguments that, when substituted by function invocation substitution (7.1.5), do not produce all constant expressions for the constructor calls andfull-expressions in the mem-initializers; [ Example:int x;//struct A {constexpr A(bool b) : m(b?42:x) { }int m;};constexpr int v = A(true).m;////constexpr int w = A(false).m;////not constantOK: constructor call initializesm with the value 42 after substitutionerror: initializer for m isx, which is non-constant— end example ]— an invocation of a constexpr function or a constexpr constructor that would exceed the implementationdefined recursion limits (see Annex B);— a result that is not mathematically defined or not in the range of representable values for its type;— a lambda-expression (5.1.2);— an lvalue-to-rvalue conversion (4.1) unless it is applied to— a glvalue of integral or enumeration type that refers to a non-volatile const object with a precedinginitialization, initialized with a constant expression, or— a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refersto a sub-object of such an object, or— a glvalue of literal type that refers to a non-volatile temporary object whose lifetime has notended, initialized with a constant expression;— an lvalue-to-rvalue conversion (4.1) that is applied to a glvalue that refers to a non-active member ofa union or a subobject thereof;— an id-expression that refers to a variable or data member of reference type unless the reference has apreceding initialization, initialized with a constant expression;— a dynamic cast (5.2.7);— a reinterpret_cast (5.2.10);— a pseudo-destructor call (5.2.4);— increment or decrement operations (5.2.6, 5.3.2);— a typeid expression (5.2.8) whose operand is of a polymorphic class type;— a new-expression (5.3.4);— a delete-expression (5.3.5);— a subtraction (5.7) where both operands are pointers;— a relational (5.9) or equality (5.10) operator where the result is unspecified;— an assignment or a compound assignment (5.17); or§ 5.19128© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— a throw-expression (15.1).3A literal constant expression is a prvalue core constant expression of literal type, but not pointer type.
Anintegral constant expression is a literal constant expression of integral or unscoped enumeration type. [ Note:Such expressions may be used as array bounds (8.3.4, 5.3.4), as bit-field lengths (9.6), as enumerator initializers if the underlying type is not fixed (7.2), as null pointer constants (4.10), and as alignments (7.6.2).
— endnote ] A converted constant expression of type T is a literal constant expression, implicitly converted to type T,where the implicit conversion (if any) is permitted in a literal constant expression and the implicit conversionsequence contains only user-defined conversions, lvalue-to-rvalue conversions (4.1), integral promotions (4.5),and integral conversions (4.7) other than narrowing conversions (8.5.4). [ Note: such expressions may be usedas case expressions (6.4.2), as enumerator initializers if the underlying type is fixed (7.2), and as integral orenumeration non-type template arguments (14.3).
— end note ] A reference constant expression is an lvaluecore constant expression that designates an object with static storage duration or a function. An addressconstant expression is a prvalue core constant expression of pointer type that evaluates to the address of anobject with static storage duration, to the address of a function, or to a null pointer value, or a prvalue coreconstant expression of type std::nullptr_t. Collectively, literal constant expressions, reference constantexpressions, and address constant expressions are called constant expressions.4[ Note: Although in some contexts constant expressions must be evaluated during program translation, othersmay be evaluated during program execution. Since this International Standard imposes no restrictions on theaccuracy of floating-point operations, it is unspecified whether the evaluation of a floating-point expressionduring translation yields the same result as the evaluation of the same expression (or the same operationson the same values) during program execution.84 [ Example:bool f() {char array[1 + int(1 + 0.2 - 0.1 - 0.1)];int size = 1 + int(1 + 0.2 - 0.1 - 0.1);return sizeof(array) == size;}// Must be evaluated during translation// May be evaluated at runtimeIt is unspecified whether the value of f() will be true or false.
— end example ] — end note ]5If an expression of literal class type is used in a context where an integral constant expression is required, thenthat class type shall have a single non-explicit conversion function to an integral or unscoped enumerationtype and that conversion function shall be constexpr.
[ Example:struct A {constexpr A(int i) : val(i) { }constexpr operator int() { return val; }constexpr operator long() { return 43; }private:int val;};template<int> struct X { };constexpr A a = 42;X<a> x;// OK: unique conversion to intint ary[a];// error: ambiguous conversion— end example ]84) Nonetheless, implementations are encouraged to provide consistent results, irrespective of whether the evaluation wasactually performed during translation or during program execution.§ 5.19© ISO/IEC 2011 – All rights reserved129ISO/IEC 14882:2011(E)61Statements[stmt.stmt]Except as indicated, statements are executed in sequence.statement:labeled-statementattribute-specifier-seqoptattribute-specifier-seqoptattribute-specifier-seqoptattribute-specifier-seqoptattribute-specifier-seqoptdeclaration-statementattribute-specifier-seqoptexpression-statementcompound-statementselection-statementiteration-statementjump-statementtry-blockThe optional attribute-specifier-seq appertains to the respective statement.6.11Labeled statement[stmt.label]A statement can be labeled.labeled-statement:attribute-specifier-seqopt identifier : statementattribute-specifier-seqopt case constant-expression : statementattribute-specifier-seqopt default : statementThe optional attribute-specifier-seq appertains to the label.
An identifier label declares the identifier. Theonly use of an identifier label is as the target of a goto. The scope of a label is the function in which itappears. Labels shall not be redeclared within a function. A label can be used in a goto statement beforeits definition. Labels have their own name space and do not interfere with other identifiers.2Case labels and default labels shall occur only in switch statements.6.21Expression statement[stmt.expr]Expression statements have the formexpression-statement:expressionopt ;The expression is a discarded-value expression (Clause 5).
All side effects from an expression statementare completed before the next statement is executed. An expression statement with the expression missingis called a null statement. [ Note: Most statements are expression statements — usually assignments orfunction calls. A null statement is useful to carry a label just before the } of a compound statement and tosupply a null body to an iteration statement such as a while statement (6.5.1).
— end note ]6.31Compound statement or block[stmt.block]So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provided.compound-statement:{ statement-seqopt }statement-seq:statementstatement-seq statement§ 6.3130© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)A compound statement defines a block scope (3.3). [ Note: A declaration is a statement (6.7).