Title
Passing constants through constexpr functions via references
Status
cd3
Section
7.7 [expr.const]
Submitter
Richard Smith

Created on 2011-12-27.00:00:00 last changed 130 months ago

Messages

Date: 2012-10-15.00:00:00

[Moved to DR at the October, 2012 meeting.]

Date: 2012-02-15.00:00:00

Proposed resolution (February, 2012):

  1. Change 7.7 [expr.const] paragraph 2 as follows:

  2. A conditional-expression is a core constant expression unless it involves one of the following...

    • ...

    • an invocation of a constexpr function with arguments that, when substituted by function invocation substitution (9.2.6 [dcl.constexpr]), do not produce a core constant expression; [Example:...

    • an invocation of a constexpr constructor with arguments that, when substituted by function invocation substitution (9.2.6 [dcl.constexpr]), do not produce all core constant expressions for the constructor calls and full-expressions in the mem-initializers; [Example:...

    • ...

    • an lvalue-to-rvalue conversion (7.3.2 [conv.lval]) unless it is applied to

      • ...

      • a glvalue of literal type that refers to a non-volatile temporary object whose lifetime has not ended, initialized with a core constant expression;

    • ...

    • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization, initialized with a constant expression; and either

      • it is initialized with a constant expression or

      • it is a non-static data member of a temporary object whose lifetime has not ended and is initialized with a core constant expression;

    • ...

  3. Change 7.7 [expr.const] paragraph 3 as follows, dividing it into two paragraphs:

  4. A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. [Note: Such expressions may be used as array bounds (9.3.4.5 [dcl.array], 7.6.2.8 [expr.new]), as bit-field lengths (11.4.10 [class.bit]), as enumerator initializers if the underlying type is not fixed (9.7.1 [dcl.enum]), as null pointer constants (7.3.12 [conv.ptr]), and as alignments (9.12.2 [dcl.align]). —end note] A converted constant expression of type T is a literal constant an expression, implicitly converted to a prvalue of type T, where the implicit conversion (if any) is permitted in a literal converted expression is a core constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-rvalue conversions (7.3.2 [conv.lval]), integral promotions (7.3.7 [conv.prom]), and integral conversions (7.3.9 [conv.integral]) other than narrowing conversions (9.4.5 [dcl.init.list]). [Note: such expressions may be used as case expressions (8.5.3 [stmt.switch]), as enumerator initializers if the underlying type is fixed (9.7.1 [dcl.enum]), and as integral or enumeration non-type template arguments (13.4 [temp.arg]). —end note]

    A literal constant expression is a prvalue core constant expression of literal type, but not pointer type (after conversions as required by the context). For a literal constant expression of array or class type, each subobject of its value shall have been initialized by a constant expression. A reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function. An address constant expression is a prvalue core constant expression (after conversions as required by the context) of type std::nullptr_t or of pointer type that evaluates to the address of an object with static storage duration, to the address of a function, or to a null pointer value, or a prvalue core constant expression of type std::nullptr_t. Collectively, literal constant expressions, reference constant expressions, and address constant expressions are called constant expressions.

  5. Change the second example 9.2.6 [dcl.constexpr] paragraph 5 as follows:

  6.   constexpr int f(bool b)
        { return b ? throw 0 : 0; }                  // OK
      constexpr int f() { throw 0 return f(true); }  // ill-formed, no diagnostic required
      ...
    

This resolution also resolves issue 1455.

Date: 2011-12-27.00:00:00

The current wording incorrectly appears to make the following example ill-formed:

   constexpr const int &f(const int &n) { return n; }
   constexpr int k = f(0);   // ill-formed
History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2013-05-03 00:00:00adminsetstatus: dr -> drwp
2012-11-03 00:00:00adminsetmessages: + msg4138
2012-11-03 00:00:00adminsetstatus: ready -> dr
2012-02-27 00:00:00adminsetmessages: + msg3710
2011-12-27 00:00:00admincreate