2010-11-12

N3218=10-0208

Change in 3.6.2 basic.start.init paragraph 2 as indicated:

Change in 5.19 expr.const paragraph 2:Constant initializationis performed:

- ...
- if an object with static or thread storage duration is initialized
~~such that the initialization satisfies the requirements for the object being declared with constexpr (7.1.5 dcl.constexpr).~~by a constructor call, if the constructor is a constexpr constructor, if all constructor arguments are constant expressions (including conversions), and if, after function invocation substitution (7.1.5 dcl.constexpr), every constructor call and full-expression in themem-initializers is a constant expression- if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.

Remove 5.19 expr.const paragraph 6 entirely:

- an invocation of a function other than a constexpr constructor for a literal class or a constexpr function
~~or a constexpr constructor~~[ Note: overload resolution (13.3) is applied as usual -- end note ];- ...
- an invocation of a
`constexpr`

function with arguments that, when substituted by function invocation substitution (7.1.5 dcl.constexpr)~~implicitly converted to the corresponding parameter types and substituted for the corresponding parameters in the potential constant expression of the~~, do not produce a constant expression; [ Example:`constexpr`

function, and the resulting expression implicitly converted to the return typeconstexpr const int* addr(const int& ir) { return &ir; } // OK static const int x = 5; constexpr const int* xp = addr(x); // OK: (const int*)&(const int&)x is an // address contant expression constexpr 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 temporary]- an invocation of a
`constexpr`

constructor with arguments that, when substituted by function invocation substitution (7.1.5 dcl.constexpr), do not produce all constant expressions for the constructor calls and full-expressions in themem-initializers; [ Example:int x; // not constant struct A { constexpr A(bool b) : m(b ? 42 : x) { } int m; }; constexpr int v = A(true).m; // ok, constructor call initializes // m with the value 42 after substitution constexpr int w = A(false).m; // error: initializer for m is // "x", which is non-constant]- ...
- an
id-expressionthat refers to a variable or data member of reference type; [ Footnote: Use of a reference parameter of a`constexpr`

function does not prevent the function from being used in constant expressions, because function invocation substitution will replace the parameters with the argument expressions.~~body from being a potential constant expression because the parameters are replaced by constant expressions during that determination, and later by arguments to a call.~~]- ...

Change in 7.1.5 dcl.constexpr paragraph 3 as indicated:~~An expression is a~~potential constant expressionif it is a constant expression when all occurrences of function parameters are replaced as follows:

~~for non-reference parameters, by arbitrary prvalue constant expressions of the appropriate types;~~~~for lvalue reference parameters, by arbitrary variables of the referred-to types with static storage duration initialized with constant expressions; or~~~~for rvalue reference parameters, by arbitrary prvalue constant expressions of the referred-to types implicitly converted to the types of the parameters.~~

Change 7.1.5 dcl.constexpr paragraph 4 as indicated:[ Example: ... ]

- its
function-bodyshall be acompound-statementof the form{ returnexpression; }~~where~~expressionis a potential constant expression (5.19 expr.const)

In 7.1.5 dcl.constexpr, add a new paragraph after the current paragraph 4:A trivial copy/move constructor is also a

~~every constructor argument and full-expression in a~~mem-initializershall be a potential constant expression~~constexpr~~`constexpr`

constructor. [ Example: ... ]

Change 7.1.5 dcl.constexpr paragraph 8 as indicated:Function invocation substitutionfor a call of a`constexpr`

function or of a`constexpr`

constructor means to convert implicitly each argument expression to the corresponding parameter type as if by copy-initialization [ Footnote: The resulting converted value will include an lvalue-to-rvalue conversion (4.1 conv.lval) if the corresponding copy-initialization requires one. --end footnote], to substitute that converted expression for each use of the corresponding parameter in the function-body, and, for constexpr functions, to convert implicitly the resulting expression to the return type of the function. Such substitution does not change the meaning. [ Example:constexpr int f(void *) { return 0; } constexpr int f(...) { return 1; } constexpr int g1() { return f(0); } // calls f(void *) constexpr int g2(int n) { return f(n); } // calls f(...) even for n == 0 constexpr int g3(int n) { return f(n*0); } // calls f(...) namespace N { constexpr int c = 5; constexpr int h() { return c; } } constexpr int c = 0; constexpr int g4() { return N::h(); } // value is 5, "c" is not looked up again after the substitution] For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19 expr.const), the program is ill-formed; no diagnostic required. For a constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in themem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required. [ Example:constexpr int f(bool b) { return b ? throw 0 : 0; } // ok constexpr int f() { throw 0; } // ill-formed, no diagnostic required struct B { constexpr B(int x) : i(0) { } // "x" is unused int i; }; int global; struct D : B { constexpr D() : B(global) { } // ill-formed, no diagnostic required // lvalue-to-rvalue conversion on non-constant "global" };]

A`constexpr`

specifier used in an object declaration declares the object as`const`

. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call,~~the constructor shall be a~~that call shall be a constant expression (5.19 expr.const). Otherwise, every full-expression that appears in its initializer shall be a constant expression. Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization shall be one of those allowed in a constant expression (5.19 expr.const). [ Example:`constexpr`

constructor and every argument to the constructor shall be a constant expressionstruct pixel { int x, y; }; constexpr pixel ur = { 1294, 1024 };// OK constexpr pixel origin; // error: initializer missing]