Document Number: N2546
2008-02-28
Daveed Vandevoorde <daveed@vandevoorde.com>
Jens Maurer <Jens.Maurer@gmx.net>

Removal of auto as a storage-class specifier

The Core Working Group discussed N2337 "The Syntax of auto Declarations" by Daveed Vandevoorde in Kona. The consensus was to remove the use of "auto" as a storage class specifier entirely. This paper presents proposed changes to the working paper to implement that approach, resolving core issue 629.

Proposed wording changes

Remove 3.7 basic.stc paragraph 3:
The storage class specifiers static and auto are related to storage duration as described below.
Change 3.7.2 basic.stc.auto paragraph 1 as indicated:
Local objects explicitly declared auto or register or not explicitly declared static or extern have automatic storage duration. The storage for these objects lasts until the block in which they are created exits.
Change 5.3.4 paragraph 2 as indicated:
If the auto type-specifier appears in the type-specifier-seq of a new-type-id or type-id of a new-expression, the type-specifier-seq shall contain no other type-specifiers except cv-qualifiers, and the new-expression shall contain a new-initializer of the form
       ( assignment-expression )
Change 6.4 paragraph 2 as indicated:
... If the auto type-specifier appears in the type-specifier-seq, the type-specifier-seq shall contain no other type-specifiers except cv-qualifiers, and the type of the identifier being declared is deduced from the assignment-expression as described in 7.1.6.4 dcl.spec.auto.
Add a grammar production to the end of 7.1.6 dcl.type paragraph 1:
type-specifier-seq:
       type-specifier type-specifier-seqopt
In 7.1.6 dcl.type paragraph 2, change as indicated:
As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq. The only exceptions to this rule are the following: ...
Change 7.1.6.4 dcl.type.auto paragraphs 1-3 as indicated:

The auto type-specifier has two meanings depending on the context of its use. In a decl-specifier-seq that contains at least one type-specifier (in addition to auto) that is not a cv-qualifier, the auto type-specifier specifies that the object named in the declaration has automatic storage duration. The decl-specifier-seq shall contain no storage-class-specifiers. This use of the auto specifier shall only be applied to names of objects declared in a block (6.3) or to function parameters (8.4).

Otherwise (auto appearing with no type specifiers other than cv-qualifiers), the The auto type-specifier signifies that the type of an object being declared shall be deduced from its initializer. The name of the object being declared shall not appear in the initializer expression.

This use of auto The auto type-specifier is allowed when declaring objects in a block (6.3), in namespace scope (3.3.5), and in a for-init-statement (6.5.3). The decl-specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initializer of either of the following forms:

        = assignment-expression
        ( assignment-expression )
  [ Example:
     auto x = 5;                     // OK: x has type int
     const auto *v = &x, u = 6;      // OK: v has type const int*, u has type const int
     static auto y = 0.0;            // OK: y has type double
     static auto int z;         // error: auto and static conflict
     auto int r;                     // OK: r has type interror: auto is not a storage-class-specifier
   -- end example ]
Remove the grammar production from 8.1 dcl.name paragraph 1:

type-specifier-seq:
       type-specifier type-specifier-seqopt

Change 8.3 dcl.meaning paragraph 2 as indicated:
An auto, A static, extern, register, mutable, friend, inline, virtual, or typedef specifier applies directly to each declarator-id in an init-declarator-list; the type specified for each declarator-id depends on both the decl-specifier-seq and its declarator.
Change 8.3.4 dcl.array paragraph 1 as indicated:
In a declaration T D where D has the form
       D1 [ constant-expressionopt ]
and the type of the identifier in the declaration T D1 is "derived-declarator-type-list T," then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type deduction type-specifier, the program is ill-formed. ...
Change 9.2 class.mem paragraph 6 as indicated:
A member shall not be declared to have automatic storage duration (auto, register) or with the extern or register storage-class-specifiers.
Change the example in 9.8 class.local paragraph 1 as indicated:
[ Example:
  int x;
  void f()
  {
      static int s ;
      int x;
      extern int g();
      struct local {
      int g() { return    x; }    // error: x is auto has automatic storage duration
      int h() { return    s; }    // OK
      int k() { return    ::x; }  // OK
      int l() { return    g(); }  // OK
      };
       // ...
  }
  local* p = 0;                         // error: local not in scope
-- end example ]
Add an element to C.1.5 diff.dcl (not shown in bold here):
7.1.6.4 dcl.type.auto

Change: The keyword auto cannot be used as a storage class specifier.

Example:

   void f()
   {
     auto int x;     // valid C, invalid C++
   }
Rationale: Allowing the use of auto to deduce the type of a variable from its initializer results in undesired interpretations of auto as a storage class specifier in certain contexts.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Syntactic transformation.
How widely used: Rare.
In the index, remove the entries for

auto
    destruction of,
initialization,
    auto

Change the index entry for
storage duration, 60
     autoautomatic, 61