Movatterモバイル変換


[0]ホーム

URL:


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

2025-12-20


619. Completeness of array types

Section:6.9  [basic.types]    Status:C++11    Submitter:Steve Clamage    Date:16 February 2007

[Voted into WP at August, 2010 meeting.]

Is the following example well-formed?

    struct S {        static char a[5];    };    char S::a[];    // Unspecified bound in definition

6.7 [basic.link] paragraph 10 certainly makes allowancefor declarations to differ in the presence or absence of a major arraybound. However, 6.2 [basic.def] paragraph 5 says that

A program is ill-formed if the definition of any object gives theobject an incomplete type (6.9 [basic.types]).

6.9 [basic.types] paragraph 7 says,

The declared type of an array object might be an array of unknown sizeand therefore be incomplete at one point in a translation unit andcomplete later on; the array types at those two points (“arrayof unknown bound ofT” and “array ofNT”) are different types.

This wording appears to make no allowance for the C concept of“composite type;” instead, each declaration is saidto have its own type. By this interpretation, the example isill-formed, because the type declared by the definition ofS::a is incomplete.

If the example is intended to be well-formed, the Standardneeds explicit wording stating that an omitted array bound in adeclaration is implicitly taken from that of a visibledeclaration of that object, if any.

Notes from the April, 2007 meeting:

The CWG agreed that this usage should be permitted.

Proposed resolution (June, 2008):

  1. Change 9.3.4.5 [dcl.array] paragraph 1 as follows:

  2. ...IfExcept as noted below, if the constant expressionis omitted, the type of the identifier ofD is“derived-declarator-type-list array of unknown bound ofT,” an incomplete object type...
  3. Change 9.3.4.5 [dcl.array] paragraph 3 as follows:

  4. When several “array of” specifications are adjacent, amultidimensional array is created;only the first of theconstant expressions that specify the bounds of the arrayscanmay be omittedonly for the first member of thesequence. [Note: this elision is useful for function parametersof array types, and when the array is external and the definition,which allocates storage, is given elsewhere. —endnote]In addition to declarations in which an incompleteobject type is allowed, an array bound may be omitted in thedeclaration of a function parameter (9.3.4.6 [dcl.fct]).The firstconstant-expression canAn array boundmay also be omitted when the declarator is followed by aninitializer (9.5 [dcl.init]). In this case the boundis calculated from the number of initial elements (say,N)supplied (9.5.2 [dcl.init.aggr]), and the type of the identifierofD is “array ofNT.”Furthermore, if there is a visible declaration of the name declaredby thedeclarator-id (if any) in which the bound was specified,an omitted array bound is taken to be the same as in that earlierdeclaration.

Notes from the September, 2008 meeting:

The proposed resolution does not capture the result favoredby the CWG: array bound information should be accumulated acrossdeclarations within the same scope, but a block extern declarationin a nested scope should not inherit array bound information fromthe outer declaration. (This is consistent with the treatment ofdefault arguments in function declarations.) For example:

    int a[5];    void f() {        extern int a[];        sizeof(a);    }

Although there was some confusion about the C99 wording dealingwith this case, it is probably well-formed in C99. However, itshould be ill-formed in C++, because we want to avoid theconcept of “compatible types” as it exists in C.

Proposed resolution (March, 2010):

  1. Change 9.3.4.5 [dcl.array] paragraph 1 as follows:

  2. ...IfExcept as noted below, if the constant expressionis omitted, the type of the identifier ofD is“derived-declarator-type-list array of unknown bound ofT,” an incomplete object type...
  3. Change 9.3.4.5 [dcl.array] paragraphs 3-4 as follows:

  4. When several “array of” specifications areadjacent, a multidimensional array is created;only thefirst of the constant expressions that specify the boundsof the arrayscanmay be omittedonlyfor the first member of the sequence. [Note: this elisionis useful for function parameters of array types, and when thearray is external and the definition, which allocates storage, isgiven elsewhere. —end note]In additionto declarations in which an incomplete object type is allowed, anarray bound may be omitted in some cases in the declaration of afunction parameter (9.3.4.6 [dcl.fct]).Thefirstconstant-expression canAn array boundmay also be omitted when the declarator is followed by aninitializer (9.5 [dcl.init]). In this case thebound is calculated from the number of initial elements (say,N) supplied (9.5.2 [dcl.init.aggr]), and the typeof the identifier ofD is “array ofNT.”Furthermore, if there is a precedingdeclaration of the entity in the same scope in which the boundwas specified, an omitted array bound is taken to be the same asin that earlier declaration, and similarly for the definition of astatic data member of a class.

    [Example:...

    ...can reasonably appear in an expression.Finally,

      extern int x[10];  struct S {    static int y[10];  };  int x[];                //OK: bound is 10  int S::y[];             //OK: bound is 10  void f() {    extern int x[];    int i = sizeof(x);    //error: incomplete object type  }

    end example]




[8]ページ先頭

©2009-2026 Movatter.jp