Issue 1091: Issues with external definitions

Authors: Jay Ghiron
Date: 2026-08-25
Submitted against: C23
Status: Open

Consider the following:

inline void foo(){}
inline void foo(){}

In C23 6.9.1 there is wording to forbid multiple definitions with internal linkage and to forbid multiple external definitions, but there does not appear to be any wording forbidding multiple inline definitions. This is surely not intended to be valid, however. A correction should consider whether this should be undefined behavior or a constraint violation.

Second, consider the following two translation units:

/* TU 1 */
int bar();
int main(){
return bar();
}
/* TU 2 */
static int bar(){
return 0;
}

An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a typeof operator whose result is not a variably modified type, part of the controlling expression of a generic selection, part of the expression in a generic association that is not the result expression of its generic selection, or part of a sizeof or alignof operator whose result is an integer constant expression), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.

(C23 6.9.1 "General" paragraph 5.)

The definition in the second translation unit is an external definition of the same identifier bar, so this requirement appears to be satisfied. This is surely not intended to be valid, however. Additionally, if the first translation unit did provide a definition for bar then this would be undefined because there would be two external definitions for the identifier bar. That is also surely not intended to be invalid, as it would defeat the whole purpose of internal linkage. A fix to both of these cases would be to specify "with external linkage" before the semicolon.