Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why does the standard prohibit "static int a[];"?

7 views
Skip to first unread message

Paul Eggert

unread,
Nov 3, 2003, 9:50:58 PM11/3/03
to
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?

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?

Fergus Henderson

unread,
Nov 4, 2003, 5:17:00 AM11/4/03
to
Paul Eggert <egg...@twinsun.com> writes:

>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.

Douglas A. Gwyn

unread,
Nov 4, 2003, 7:09:32 AM11/4/03
to
Fergus Henderson wrote:
> I think by now they have probably all long since forgotten!

Forgotten what? :-)

Dan Pop

unread,
Nov 4, 2003, 9:16:55 AM11/4/03
to

>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

0 new messages