structure initialization

Walter Murray walter at hpclwjm.HP.COM
Wed Jan 24 06:53:05 AEST 1990


J. E. Apedaile writs:

[sample program containing the following declarations]

struct exp1 {
    int length;
    long grp1;
    long grp2;
};
typedef struct {
    struct exp1 blk[5];
} RANGE;
    static RANGE example = {
	{ 40,	0xcf000,	0xff000 },
	{ 50,	0x1cf000,	0x1ff000 },
	{ 60,	0x2cf000,	0x2ff000 },
	{ 70,	0x3cf000,	0x3ff000 },
	{ 80,	0x4cf000,	0x4ff000 },
    };

> The AT&T compiler and gcc will both compile with out errors if the five
> sets of braces surrounding each group of three items in the initialization
> are removed.  A quick look through K&R1 did not find anything which would 
> lead me to believe that the code as written is wrong.  It seems to me that
> forcing the initialization to be 1 group of 15 items instead of 5 groups of
> 3 items does not make code maintenance easier but harder, especially if the
> structure definition and typedef are in a header file.

The problem here is not too many braces, but too few.  You don't have
"5 groups of 3 items", but rather "1 group of 5 groups of 3 items".
The fully-bracketed initialization would look like this:

    static RANGE example = { {
	{ 40,	0xcf000,	0xff000 },
	{ 50,	0x1cf000,	0x1ff000 },
	{ 60,	0x2cf000,	0x2ff000 },
	{ 70,	0x3cf000,	0x3ff000 },
	{ 80,	0x4cf000,	0x4ff000 },
    } };

Note that the initializer begins with three left braces:  one for
example (a struct), one for example.blk (an array), and one for
example.blk[0] (a struct).

It is permitted to elide (omit) some of the braces, but doing so
introduces an ambiguity, depending on whether the compiler parses
the initializer top-down or bottom-up.  Compilers that accept the
example as originally given are probably using a bottom-up parse;
K&R-I and the Standard both require a top-down parse.  A
Standard-conforming compiler is required to produce a diganostic
for the program as originally written, because it looks like you
are trying to initialize 5 members in example, but example has only
1 member.

You are lucky the compiler complained.  There are situations where
the two methods of parsing initializers will yield different
results and no diagnostic.  The only safe approach is to write all
braces, or to omit all but the outermost pair.  Eliding some but
not all is likely to result in portability problems.

> Why is this no longer allowed?

The Standard and its Rationale discuss this at some length.  In the
words of the Rationale, "The Standard has reaffirmed the (top-down)
parse described in the Base Document [K&R-I]."  In K&R-I, reread the
last two paragraphs on page 198.

> Any comments?

I think Andrew Koenig ought to include an example of this in the next edition
of _C Traps and Pitfalls_.

Walter Murray
-------------



More information about the Comp.lang.c mailing list