Authors: Jay Ghiron
Date: 2026-09-01
Submitted against: C23
Status: Open
Consider the second declaration in the following:
static int x;
extern int x;
For an identifier declared with the storage-class specifier
externin 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 later declaration is the same as 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.
(C23 6.2.2 "Linkages of identifiers" paragraph 4.)
There is a prior declaration visible with internal linkage, so according to this paragraph the linkage should be internal.
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier
extern. If the declaration of an identifier for an object has file scope and does not contain the storage-class specifierstaticorconstexpr, its linkage is external.
(C23 6.2.2 "Linkages of identifiers" paragraph 5.)
The second declaration does have file scope and does not contain
either of the storage-class specifiers static or constexpr, so
according to this paragraph the linkage is external.
This wording was changed in C23 to work with type inference and
thread_local correctly, but it incorrectly also now covers the case
where extern is used.
Modify C23 6.2.2 paragraph 5:
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier
extern. If the declaration of an identifier for an object has file scope and does not contain any of the storage-class specifiersextern,static, orconstexpr, its linkage is external.
Comment from Issues list maintainer on 2026-09-09:
In reflector message 37790, Jens Gustedt suggested alternative wording changes.
If an identifier for a function or object is declared with the storage class specifier
externwhere a prior declaration with linkage of that identifier is visible, the linkage of the identifier is the same as for the prior declaration. If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifierextern. If the declaration of an identifier for an object has file scope and does not contain the storage-class specifierstaticorconstexpr, its linkage is external.
Comment from Jay Ghiron on 2026-09-14:
This does not seem to fix the issue. The added text would be a copy of the text in the preceding paragraph and does not resolve the linkage being defined multiple times with contradictory answers.