Aggregate Declarations without Braces

Steven McGeady mcg at omepd
Sat Sep 13 04:25:32 AEST 1986

A question has arisen among some colleagues of mine as to whether the
following lines of C code are valid declarations:

	char c[1] = 'a';
	int a[1] = 1;
	int b[2] = 1;
	typedef struct { int a; } fakeint; fakeint i = 1;

The following is a message (from me, incidentally), trying to defend
this practice as legal, despite a dramatic lack of (direct) support from
either K&R or X3J11.

As pointed out below, this works on PCC (both PCC and PCC-2/QCC, as though
it mattered).

Any informed comments on this subject would be welcomed, preferably
directed via mail to me, rather than to the net.  I promise to digest
the responses and post them.

S. McGeady
Oregon Microcomputer Engineering
Intel, Corp

tektronix!psu-cs!omepd!mcg, sun!verdix!inteloa!omepd!mcg

---------- Forwarded Message

On page 198 of K&R, in section 8.6:

	"When the declared variable is an aggregate ... then the
	 initializer consists of a brace-enclosed, comma-separated list
	 of initializers ...

	 Braces may be elided as follows.  ... If, however, the initializer
	 does not begin with a left brace, then only enough elements from
	 the list are taken to account for the members of the aggregate ..."

Admittedly this is weak justification (that is, in a context whose applicability
could be argued), but it does establish a precedent for elision of braces.
The only issue is whether one can elide the braces around a single initializer
at the top level.

For this I rely on the syntax description:

in K&R:
		declarator initializer

		= expression
		= { initializer-list }
		= { initializer-list , }

		initializer , initializer-list
		{ initializer-list }

This implies that

	declarator = expression ;

is syntactically legal (The Standard says the same thing in a much more
confusing way.  So we're arguing about semantics of intialization
of aggregates here, not the syntax.  I argue that K&R, in the above
paragraph, does not rule out elision of the outermost set of braces
if the initializer-list is a single element.  I argue further that
the Standard, in introducing the word "shall", and mucking with the
language with respect to elision of braces, has confused the issue
without clearly resolving it.  Finally, I agrue that the lack of mention
of this change from PCC in the Rationale means that X3J11 hasn't thought
of this issue yet.

Furthermore, stretching a bit, I can argue that this is very useful.
Take the example:

	typedef struct { int a; } fakeint;

	fakeint i = 1;

This kind of 'conveniance' has precedent in the 'char foo[] = "abcdef";'

Whatever else is true, the answer isn't clearly spelled out in either K&R
or the Standard.  PCC allows it, at least some existing code uses it
(even outside our test suite).

If there's a good reason why it shouldn't be in there, I will, of course, 
entertain the idea of backing it out.  But at this stage I can't think of
anything that leaving it in will break.

------------ End of Forwarded Message

More information about the Comp.lang.c mailing list