Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!world!mkahl From: mkahl@world.std.com (Michael Kahl) Newsgroups: comp.std.c Subject: Re: 3.7.2 External Object Definitions Keywords: external,linkage,declaration,definition Message-ID: <1991Feb7.151640.21840@world.std.com> Date: 7 Feb 91 15:16:40 GMT References: <131@tdatirv.UUCP> Organization: The World @ Software Tool & Die Lines: 52 In article <131@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: >In article eyal@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@world.std.com -or- 75236.3146@compuserve.com Disclaimer: Keep this quiet; what my employer doesn't know won't get me fired.