/*1*/
static int a[];
int main (void) { return a[1]; }
static int a[2] = { 37, 0 };
does not conform to C99. It violates section 6.9.2 of the standard,
which prohibits a tentative definition that has both internal linkage
and incomplete type.
If we make 'a' external, the program conforms:
/*2*/
extern int a[];
int main (void) { return a[1]; }
extern int a[2] = { 37, 0 };
Is there any reason for this seeming inconsistency?
I ran into the problem in an alpha version of GNU tar, which used a
construction like /*1*/. Many (perhaps most?) C compilers silently
accept /*1*/ as an extension (as they are entitled to do as it does
not violate any constraint). I don't see why the C Standard prohibits
/*1*/. Perhaps the prohibition was inadvertant?
>The following program:
>
>/*1*/
>static int a[];
>int main (void) { return a[1]; }
>static int a[2] = { 37, 0 };
>
>does not conform to C99.
Likewise for C89.
>It violates section 6.9.2 of the standard,
>which prohibits a tentative definition that has both internal linkage
>and incomplete type.
...
>Is there any reason for this?
I asked the same question about five years ago [1]. I did not get any
really satisfactory answers. Karl Heuer asked it ten years ago [2],
and he didn't get any answers either. Thirteen years ago, Doug Gywn [3]
lamented about this issue not being explained in the Rationale:
| I hope before everyone else in X3J11 forgets why the rules
| ended up the way they did, somebody documents it. The Rationale
| doesn't appear to cover this.
I think by now they have probably all long since forgotten!
References
----------
[1] See the following threads:
<http://groups.google.com.au/groups?selm=79uf15%241d2%241%40mulga.cs.mu.OZ.AU>
<http://groups.google.com.au/groups?selm=6svrop%24b20%241%40nntpd.lkg.dec.com>
<http://groups.google.com.au/groups?selm=6slfg7%24f20%241%40mulga.cs.mu.OZ.AU>
[2] See
<http://groups.google.com.au/groups?selm=23u205%24baa%40paperboy.osf.org>.
[3] See <http://groups.google.com.au/groups?selm=12248%40smoke.BRL.MIL>.
--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
Forgotten what? :-)
>The following program:
>
>/*1*/
>static int a[];
>int main (void) { return a[1]; }
>static int a[2] = { 37, 0 };
>
>does not conform to C99. It violates section 6.9.2 of the standard,
>which prohibits a tentative definition that has both internal linkage
>and incomplete type.
>
>If we make 'a' external, the program conforms:
>
>/*2*/
>extern int a[];
>int main (void) { return a[1]; }
>extern int a[2] = { 37, 0 };
>
>Is there any reason for this seeming inconsistency?
Most likely, to simplify single pass compilation. If a is extern, its
address is left to the linker to resolve. If it's local and the compiler
hasn't yet seen its definition (and therefore allocated it), there is a
problem.
Back in the eighties, when this rule was introduced in the standard,
there were some C compilers written for resource starved platforms and
even implementing the K&R1 syntax was a bit of a challenge. Someone in
the committee must have been thinking at such compilers when coming up
with this rule. Pure speculation...
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de