Title
Use of block-scope constants in local classes
Status
c++11
Section
11.6 [class.local]
Submitter
Steve Adamczyk

Created on 2008-05-29.00:00:00 last changed 91 months ago

Messages

Date: 2009-10-15.00:00:00

Notes from the October, 2009 meeting:

There was interest in an approach that would allow explicitly-captured constants to appear in constant expressions but also to be “used.” Another suggestion was to have variables captured if they appear in either “use” or “non-use” contexts.

Date: 2011-03-15.00:00:00

[Voted into the WP at the March, 2011 meeting.]

Date: 2011-02-15.00:00:00

Proposed resolution (February, 2011):

  1. Change 7.5.5 [expr.prim.lambda] paragraph 17 as follows:

  2. Every id-expression that is an odr-use (6.3 [basic.def.odr]) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [Note: an id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. Furthermore, such an id-expression does not cause the implicit capture of the entity. —end note] If this is captured, each odr-use of this is transformed into an access to the corresponding unnamed data member of the closure type, cast (7.6.3 [expr.cast]) to the type of this. [Note: the cast ensures that the transformed expression is a prvalue. —end note] [Example:

      void f(const int*);
      void g() {
        const int N = 10;
        [=] {
          int arr[N];    // OK: not an odr-use, refers to automatic variable
          f(&N);         // OK: causes N to be captured; &N points to the
                         // corresponding member of the closure type
        }
      }
    

    end example]

  3. Change 11.6 [class.local] paragraph 1 as follows:
  4. ...Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the shall not odr-use (6.3 [basic.def.odr]) a variable with automatic storage duration from an enclosing scope. [Example:

      int x;
      void f() {
        static int s ;
        int x;
        const int N = 5;
        extern int g q();
    
        struct local {
          int g() { return x; }     // error: odr-use of automatic variable x has automatic storage duration
          int h() { return s; }     // OK
          int k() { return ::x; }   // OK
          int l() { return g q(); } // OK
          int m() { return N; }     // OK: not an odr-use
          int* n() { return &N; }   // error: odr-use of automatic variable N
        };
      }
    
      local* p = 0;                 // error: local not in scope
    

    end example]

Date: 2009-10-15.00:00:00

Notes from the October, 2009 meeting:

There was interest in an approach that would allow explicitly-captured constants to appear in constant expressions but also to be “used.” Another suggestion was to have variables captured if they appear in either “use” or “non-use” contexts.

Date: 2008-09-15.00:00:00

Notes from the September, 2008 meeting:

The CWG agreed that both uses of local_const in the example above should be accepted. The intent of the restriction was to avoid the need to pass a frame pointer into local class member functions, so uses of local const variables as values should be permitted.

Date: 2008-05-29.00:00:00

According to 11.6 [class.local] paragraph 1,

Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.

This would presumably make both of the members of S2 below ill-formed:

    void test () {
      const int local_const = 7;
      struct S2 {
        int member:local_const;
        void f() { int j = local_const; }
      };
    }

Should there be an exception to this rule for constant values? Current implementations seem to accept the reference to local_const in the bit-field declaration but not in the member function definition. Should they be the same or different?

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: tentatively ready -> fdis
2011-02-28 00:00:00adminsetstatus: drafting -> tentatively ready
2009-11-08 00:00:00adminsetmessages: + msg2387
2009-11-08 00:00:00adminsetstatus: review -> drafting
2009-09-29 00:00:00adminsetmessages: + msg2307
2009-09-29 00:00:00adminsetstatus: drafting -> review
2009-08-03 00:00:00adminsetmessages: + msg2199
2009-08-03 00:00:00adminsetstatus: review -> drafting
2008-10-05 00:00:00adminsetmessages: + msg1768
2008-10-05 00:00:00adminsetmessages: + msg1767
2008-10-05 00:00:00adminsetstatus: open -> review
2008-05-29 00:00:00admincreate