3.7.2 External Object Definitions

Michael Kahl mkahl at world.std.com
Fri Feb 8 02:16:40 AEST 1991


In article <131 at tdatirv.UUCP> sarima at tdatirv.UUCP (Stanley Friesen) writes:
>In article <eyal.665840220 at echo> eyal at echo.canberra.edu.au (Eyal Lebedinsky) writes:
>>I tried gnu (1.39) which I hope is ANSI by now. It likes this one:
>>
>>(1)	extern int i7;
>>(2)	static int i7 = 1;
>
>Well, then it is wrong.  (1) is a tentative definition with *external* linkage.
>As such it is incompatible with (2), which is illegal in the same scope.
>[(1) is external by 3.1.2.2 paragraph 4, the incompatibility is required
>by paragraph 7].

Exactly right... except: it's not really "illegal".  Paragraph 7 says "if,
within a translation unit, the same identifier appears with both internal
and external linkage, the behavior is undefined."  Undefined, not illegal.
Therefore, this construct should be avoided in portable programs, but gcc
is perfectly within its rights to accept the usage.

>>It hates this one:
>>
>>	static int i7;		/* tentative definition, internal linkage */
>>(3)	extern int i7 = 1;
>
>Beep, Gnu is wrong again!  This is actually the correct way to do it.

Right.  An ANSI compiler should accept this.

>>Microsoft 5.1 likes both, but I wouldn't trust it much.
>
>Well, at least it is only half wrong.  It is *required* to diagnose (2)
>if it follows (1).

Wrong.  The behavior is undefined.  This is neither a constraint violation
nor a syntax violation, and so no diagnosis is required.

IMHO, allowing an "extern" forward declaration followed later by a definition
of the identifier as "static" is a reasonable extension to the language.  In
some pre-ANSI compilers, this was the *only* way to forward-declare a name
not meant to be exported.  In deference to existing code, it is reasonable
to accept this usage.  The Standard permits this extension by leaving
the behavior undefined.

I don't know this for a fact, but I like to think that it was for this very
reason that the committee left it undefined rather than requiring a diagnosis.
Neither did they did not mandate this treatment, presumably so as not to place
undue burden on compilers that need to address variables differently depending
on their linkage, and don't read the entire source file before starting to
generate code. 
-- 
Michael Kahl, Symantec Corporation
mkahl at world.std.com  -or-  75236.3146 at compuserve.com
Disclaimer:  Keep this quiet; what my employer doesn't know won't get me fired.



More information about the Comp.std.c mailing list