Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!samsung!brutus.cs.uiuc.edu!apple!motcsd!hpda!hpcuhb!hpcllla!hpclisp!hpclwjm!walter From: walter@hpclwjm.HP.COM (Walter Murray) Newsgroups: comp.lang.c Subject: Re: structure initialization Message-ID: <660073@hpclwjm.HP.COM> Date: 23 Jan 90 19:53:05 GMT References: <1515@pttesac.UUCP> Organization: Hewlett-Packard Calif. Language Lab Lines: 74 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 -------------