Defect Report #011
Submission Date: 10 Dec 92
Submittor: WG14
Source: X3J11/90-008 (Rich Peterson)
Question 1
Merging of declarations for linked identifier
When more than one declaration is present in a program for an
externally-linked identifier, exactly when do the declared types get
formed into a composite type?
Certainly, if two declarations have file scope, then after the
second, the effective type for semantic analysis is the composite type
of the two declarations (subclause 6.1.2.6, page 25, lines 19-20).
However, if one declaration is in an inner scope and one is in an outer
scope, are their types formed into a composite type?
In particular, consider the code:
{
extern int i[];
{
/* a different
declaration of the same object */
extern int i[10];
}
/* Is the following legal?
That is, does the
outer declaration
inherit any information from the inner one?
*/
sizeof (i);
}
Similar situations can be constructed with internally
linked identifiers. For instance:
/* File scope */
static int i[];
main()
{
/* a different declaration of the same
object
*/
extern int i[10];
}
/* Is the following legal?
That is, does the outer
declaration
inherit any information from the inner one?*/
int j = sizeof (i);
Further variants of this question can be asked:
{
extern int i[10];
{
/* a different
declaration of the same object */
extern int i[];
/* Is the following legal?
That is, does
the inner declaration
inherit any information from the outer
one? */
sizeof (i);
}
}
Correction
In subclause 6.1.2.6, page 25, lines 19-20, change:
For an identifier with external or internal linkage declared in
the same scope as another declaration for that identifier, the type of
the identifier becomes the composite type.
to:
For an identifier with internal or external linkage declared in a
scope in which a prior declaration of that identifier is visible*,
if the prior declaration specifies internal or external linkage, the
type of the identifier at the latter declaration becomes the composite
type.
[Footnote *: As specified in 6.1.2.1, the latter declaration
might hide the prior declaration.]
Question 2
Interpretation of extern
Consider the code:
/* File scope */
static int i;
/* declaration 1 */
main()
{
extern int i; /* declaration
2 */
{
extern int i; /* declaration
3 */
}
}
A literal reading of subclause 6.1.2.2 says that
declarations 1 and 2 have internal linkage, but that declaration 3 has
external linkage (since declaration 1 is not visible, being hidden by
declaration 2). (This combination of internal and external linkage is
undefined by subclause 6.1.2.2, page 21, lines 27-28.)
Is this what is intended?
Correction
In subclause 6.1.2.2, page 21, change:
If the declaration of an identifier for an object or a function
contains the storage-class specifier extern, the
identifier has the same linkage as any visible declaration of the
identifier with file scope. If there is no visible declaration with file
scope, the identifier has external linkage.
to:
For an identifier declared with the
storage-class specifier extern in a scope in which a
prior declaration of that identifier is visible*, if the prior
declaration specifies internal or external linkage, the linkage of the
identifier at the latter declaration becomes the linkage specified at
the prior declaration. If no prior declaration is visible, or if the
prior declaration specifies no linkage, then the identifier has external
linkage. [Footnote *: As specified in 6.1.2.1, the latter declaration
might hide the prior declaration.]
Question 3
Initialization of tentative definitions
If the file scope declaration
int i[10];
appears in a translation unit, subclause 6.7.2 suggests that it
is implicitly initialized as if
int i[10] = 0;
appears at the end of the translation unit. However, this
initializer is invalid, since subclause 6.5.7 prescribes that the
initializer for any object of array type must be brace-enclosed. We
believe that the intention of subclause 6.7.2 is that this declaration
has an implicit initializer of
int i[10] = {0};
Is this true?
Response
Subclause 6.7.2 External object definitions contains the
following excerpt:
If a translation unit contains one or more tentative definitions
for an identifier, and the translation unit contains no external
definition for that identifier, then the behavior is exactly as if the
translation unit contains a file scope declaration of that identifier,
with the composite type as of the end of the translation unit, with an
initializer equal to 0.
This statement describes an effect and not a literal token
sequence. Therefore, this example does not contain an error.
Question 4
Tentative definition of externally-linked object with incomplete
type
If one writes the file-scope declaration
int i[];
then subclause 6.7.2 suggests that at the end of the translation
unit the implicit declaration
int i[] = {0};
or equivalently
int i[1] = {0};
appears. This seems peculiar, since subclause 6.7.2, (page 83,
lines 35-36) specifically forbids this case for internally linked
identifiers.
Is this what is intended?
Correction
Add to subclause 6.7.2, page 84, a second Example:
If at the end of the translation unit containing
int i[];
the array i still has incomplete type, the array
is assumed to have one element. This element is initialized to zero on
program startup.
Previous Defect Report
< - > Next Defect Report