Title
Referring to parameters in unevaluated operands of default arguments
Status
cd4
Section
9.3.4.7 [dcl.fct.default]
Submitter
Faisal Vali

Created on 2015-02-09.00:00:00 last changed 49 months ago

Messages

Date: 2015-10-15.00:00:00

Proposed resolution (October, 2015):

  1. Change 9.3.4.7 [dcl.fct.default] paragraph 7 as follows:

  2. Local variables A local variable shall not be used appear as a potentially-evaluated expression in a default argument. [Example:

      void f() {
        int i;
        extern void g(int x = i);           // error
        extern void h(int x = sizeof(i));   // OK
        // ...
      }
    

    end example]

  3. Change 9.3.4.7 [dcl.fct.default] paragraph 8 as follows:

  4. [Note: The keyword this shall may not be used appear in a default argument of a member function; see _N4567_.5.1.1 [expr.prim.general]. [Example:

      class A {
        void f(A* p = this) { } // error
      };
    

    end example] end note]

  5. Change 9.3.4.7 [dcl.fct.default] paragraph 9 as follows:

  6. A default argument is evaluated each time the function is called with no argument for the corresponding parameter. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. A parameter shall not appear as a potentially-evaluated expression in a default argument. Parameters of a function declared before a default argument are in scope and can hide namespace and class member names. [Example:

      int a;
      int f(int a, int b = a);         // error: parameter a
                                       // used as default argument
      typedef int I;
      int g(float I, int b = I(2));    // error: parameter I found
      int h(int a, int b = sizeof(a)); // error, parameter a used OK, unevaluated operand
                                         // in default argument
    

    end example] Similarly, a A non-static member shall not be used appear in a default argument, even if it is not evaluated, unless it appears as the id-expression of a class member access expression (7.6.1.5 [expr.ref]) or unless it is used to form a pointer to member (7.6.2.2 [expr.unary.op]). [Example:...

Date: 2016-02-15.00:00:00

[Adopted at the February, 2016 meeting.]

According to 9.3.4.7 [dcl.fct.default] paragraph 9,

A default argument is evaluated each time the function is called with no argument for the corresponding parameter. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.

This prohibits use of parameters in unevaluated operands, e.g.,

  void foo(int a = decltype(a){});

This wording predates the concept of “unevaluated operands” (the phrase “not evaluated” refers to calls to the function where an actual argument is supplied and thus the default argument is not used, not to unevaluated operands) and should not apply to such cases.

History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: ready -> cd4
2015-11-10 00:00:00adminsetmessages: + msg5579
2015-11-10 00:00:00adminsetstatus: drafting -> ready
2015-02-09 00:00:00admincreate