This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


379. Change "class declaration" to "class definition"

Section: Clause 11  [class]     Status: CD1     Submitter: Jens Maurer     Date: 21 Oct 2002

[Voted into WP at March 2004 meeting.]

The ARM used the term "class declaration" to refer to what would usually be termed the definition of the class. The standard now often uses "class definition", but there are some surviving uses of "class declaration" with the old meaning. They should be found and changed.

Proposed resolution (April 2003):

Replace in 6.2 [basic.def] paragraph 2

A declaration is a definition unless it declares a function without specifying the function's body (9.5 [dcl.fct.def]), it contains the extern specifier (9.2.2 [dcl.stc]) or a linkage-specification [Footnote: Appearing inside the braced-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition. --- end footnote] (9.11 [dcl.link]) and neither an initializer nor a function-body, it declares a static data member in a class declaration definition (11.4.9 [class.static]), it is a class name declaration (11.3 [class.name]), or it is a typedef declaration (9.2.4 [dcl.typedef]), a using-declaration (9.9 [namespace.udecl]), or a using-directive (9.8.4 [namespace.udir]).

Replace in 9.2.3 [dcl.fct.spec] paragraphs 5 and 6

The virtual specifier shall only be used in declarations of nonstatic class member functions that appear within a member-specification of a class declaration definition; see 11.7.3 [class.virtual].

The explicit specifier shall be used only in declarations of constructors within a class declaration definition; see 11.4.8.2 [class.conv.ctor].

Replace in 9.2.4 [dcl.typedef] paragraph 4

A typedef-name that names a class is a class-name (11.3 [class.name]). If a typedef-name is used following the class-key in an elaborated-type-specifier (9.2.9.5 [dcl.type.elab]) or in the class-head of a class declaration definition (Clause 11 [class]), or is used as the identifier in the declarator for a constructor or destructor declaration (11.4.5 [class.ctor], 11.4.7 [class.dtor]), the program is ill-formed.

Replace in _N4868_.9.8.2.3 [namespace.memdef] paragraph 3

The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration definition granting friendship).

Replace in 9.3.4.3 [dcl.ref] paragraph 4

There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer (9.4.4 [dcl.init.ref]) except when the declaration contains an explicit extern specifier (9.2.2 [dcl.stc]), is a class member (11.4 [class.mem]) declaration within a class declaration definition, or is the declaration of a parameter or a return type (9.3.4.6 [dcl.fct]); see 6.2 [basic.def].

Replace in 9.4.4 [dcl.init.ref] paragraph 3

The initializer can be omitted for a reference only in a parameter declaration (9.3.4.6 [dcl.fct]), in the declaration of a function return type, in the declaration of a class member within its class declaration definition (11.4 [class.mem]), and where the extern specifier is explicitly used.

Replace in 11.3 [class.name] paragraph 2

A class definition declaration introduces the class name into the scope where it is defined declared and hides any class, object, function, or other declaration of that name in an enclosing scope (6.4 [basic.scope]). If a class name is declared in a scope where an object, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier (6.5.6 [basic.lookup.elab]).

Replace in 11.4.9 [class.static] paragraph 4

Static members obey the usual class member access rules ( 11.8 [class.access]). When used in the declaration of a class member, the static specifier shall only be used in the member declarations that appear within the member-specification of the class declaration definition.

Replace in 11.4.12 [class.nest] paragraph 1

A class can be defined declared within another class. A class defined declared within another is called a nested class. The name of a nested class is local to its enclosing class. The nested class is in the scope of its enclosing class. Except by using explicit pointers, references, and object names, declarations in a nested class can use only type names, static members, and enumerators from the enclosing class.

Replace in 11.6 [class.local] paragraph 1

A class can be defined declared within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.

Replace in 11.7 [class.derived] paragraph 1

... The class-name in a base-specifier shall not be an incompletely defined class (Clause 11 [class]); this class is called a direct base class for the class being declared defined. During the lookup for a base class name, non-type names are ignored (_N4868_.6.4.10 [basic.scope.hiding]). If the name found is not a class-name, the program is ill-formed. A class B is a base class of a class D if it is a direct base class of D or a direct base class of one of D's base classes. A class is an indirect base class of another if it is a base class but not a direct base class. A class is said to be (directly or indirectly) derived from its (direct or indirect) base classes. [Note: See 11.8 [class.access] for the meaning of access-specifier.] Unless redefined redeclared in the derived class, members of a base class are also considered to be members of the derived class. The base class members are said to be inherited by the derived class. Inherited members can be referred to in expressions in the same manner as other members of the derived class, unless their names are hidden or ambiguous (6.5.2 [class.member.lookup]). [Note: the scope resolution operator :: (_N4567_.5.1.1 [expr.prim.general]) can be used to refer to a direct or indirect base member explicitly. This allows access to a name that has been redefined redeclared in the derived class. A derived class can itself serve as a base class subject to access control; see 11.8.3 [class.access.base]. A pointer to a derived class can be implicitly converted to a pointer to an accessible unambiguous base class (7.3.12 [conv.ptr]). An lvalue of a derived class type can be bound to a reference to an accessible unambiguous base class (9.4.4 [dcl.init.ref]).]

Replace in 11.7.2 [class.mi] paragraph 5

For another example,
class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };
for an object c of class type C, a single subobject of type V is shared by every base subobject of c that is declared to have has a virtual base class of type V.

Replace in the example in 6.5.2 [class.member.lookup] paragraph 6 (the whole paragraph was turned into a note by the resolution of core issue 39)

The names defined declared in V and the left hand instance of W are hidden by those in B, but the names defined declared in the right hand instance of W are not hidden at all.

Replace in 11.7.4 [class.abstract] paragraph 2

... A virtual function is specified pure by using a pure-specifier (11.4 [class.mem]) in the function declaration in the class declaration definition. ...

Replace in the footnote at the end of 11.8.3 [class.access.base] paragraph 1

[Footnote: As specified previously in 11.8 [class.access], private members of a base class remain inaccessible even to derived classes unless friend declarations within the base class declaration definition are used to grant access explicitly.]

Replace in _N3225_.11.3 [class.access.dcl] paragraph 1

The access of a member of a base class can be changed in the derived class by mentioning its qualified-id in the derived class declaration definition. Such mention is called an access declaration. ...

Replace in the example in 12.3 [over.over] paragraph 5

The initialization of pfe is ill-formed because no f() with type int(...) has been defined declared, and not because of any ambiguity.

Replace in C.7.6 [diff.dcl] paragraph 1

Rationale: Storage class specifiers don't have any meaning when associated with a type. In C++, class members can be defined declared with the static storage class specifier. Allowing storage class specifiers on type declarations could render the code confusing for users.

Replace in C.7.7 [diff.class] paragraph 3

In C++, a typedef name may not be redefined redeclared in a class declaration definition after being used in the declaration that definition
Drafting notes:

The resolution of core issue 45 (DR) deletes 11.8.8 [class.access.nest] paragraph 2.

The following occurrences of "class declaration" are not changed: