simpsong@ncoast.UUCP (03/14/87)
*** Line eater food *** I have a structure like this: =============================== struct of_stuff { char *name float value; float another; int counter; } stuff[20][30] = { { "joe", 1, 0, 12, "fred", 1, 0, 13, "carol",1, 0, 4 } , { "joe", 1, 0, 12, "fred", 1, 0, 13, "carol",1, 0, 4 } } ====================================== This works fine on VMS 4.5 (VMS C - 4.?) and on my PC using MS C 3.0. However, when I tried it on a vax 11/780 running 4.3BSD and a Sun workstation running whatever they call Unix (the latest 3.0 I believe), I got an error. The error was repeated 4 times for each line that has a name in it (like "joe"), the error said I was missing a }. (or something to that effect.) My question is: What is the proper way to initialize a two dimensional array of structures... Thanks for any help, I thought I had it right till I tried BSD... Greg -- Gregory R. Simpson UUCP: {ihnp4, seismo, decwrl, philabs, ucbvax}!decvax!cwruecmp!ncoast!simpsong CSNET: ncoast!simpsong@case.CSNET ARPA: ncoast!simpsong%case.CSNET@Csnet-Relay.ARPA
throopw@dg_rtp.UUCP (Wayne Throop) (03/20/87)
> simpsong@ncoast.UUCP (Gregory R. Simpson @ The North Coast) > I have a structure like this: > struct of_stuff { > char *name; float value; float another; int counter; > } > stuff[20][30] = {{ [...value-list...] },{ [...value-list...] }}; > This works fine on VMS 4.5 (VMS C - 4.?) and on my PC using MS C 3.0. > However, when I tried it on a vax 11/780 running 4.3BSD and a Sun workstation > running whatever they call Unix (the latest 3.0 I believe), I got an error. > The error was repeated 4 times for each line that has a name in it > (like "joe"), the error said I was missing a }. (or something to that effect.) Right. You are missing a level of curly braces. Some compilers are forgiving of this, and some are not. It is probably best to put in all levels of braces necessary, even though I think K&R and X3J11 allow some shortcuts. This example linted and compiled correctly for me: typedef struct stuff_s { char *name; float value; float another; int counter; } stuff_t; stuff_t stuff[20][30] = { { { "00", 1, 2, 3 }, { "01", 4, 5, 6 } },{ { "10", 7, 8, 9 }, { "11", 10, 11, 12 } } }; > My question is: What is the proper way to initialize a two dimensional > array of structures... Well, the idea I keep in mind is that what follows the equal sign is a SINGLE VALUE that is the initial value of the object you are declaring. If that object is an aggregate object (an array or a structure), it becomes a curly-brace-enclosed comma-separated list of member initial values. From there we recurse. So, since what we have here is an array of array of struct of four members, we open a curly (we now are ready to give a value for an array of struct of four members) open another curly (we now are ready to give a value for a struct of four members) open another curly (we are now ready to give a value for a struct member) list four values separated by commas, close a curly, insert a comma (we are now back up one level, giving the next value for an array of struct of four members), open a curly.... and so on and on. Note that in the example I've given, I've initialized stuff[0][0], stuff[0][1], stuff[1][0], and stuff[1][1]. The problem is, in the original example, it wasn't totally clear just what was being initialized to what. The extra level of curly braces makes it unambiguous. -- Big Mac had a heart attack in the back of a yellow cab, After he'd stiffed his waitress and run out on his tab. By the time the sound of the siren said the ambulance was coming, His heart had stopped beating, but the meter was still running. Life is hard. --- Timbuk3 -- Wayne Throop <the-known-world>!mcnc!rti-sel!dg_rtp!throopw
michael@slovax.UUCP (03/20/87)
> I have a structure like this: > =============================== > > struct of_stuff { > char *name > float value; > float another; > int counter; > } > > stuff[20][30] = { > { > "joe", 1, 0, 12, > "fred", 1, 0, 13, > "carol",1, 0, 4 } > , > { > "joe", 1, 0, 12, > "fred", 1, 0, 13, > "carol",1, 0, 4 } > } > > > ... when I tried it on a vax 11/780 running 4.3BSD and a Sun workstation > running whatever they call Unix (the latest 3.0 I believe), I got an error. > > Gregory R. Simpson Ditto here on BSD. It compiled okay with the addition of another level of matching {}: stuff[20][30] = { { {"joe", 1, 0, 12}, {"fred", 1, 0, 13}, {"carol",1, 0, 4} } } K&R p. 124 says, for a particular example, "... It would be more precise to enclose initilizers for each 'row' or structure in braces, ... but the inner braces are not necessary when the initializers are simple variables or character strings, and when all are present." Apparently some compilers prefer the inner braces. It doesn't hurt to have them in either case. Michael Longe' R & D Associates ..!tikal!slovax!michael ------ standard disclaimer ------------------------------------------------- I work in C, and my employers know it. ------ usual exclaimer ----------------------------------------------------- Qui, moi?
mouse@mcgill-vision.UUCP (03/22/87)
In article <2173@ncoast.UUCP>, simpsong@ncoast.UUCP (Gregory R. Simpson @ The North Coast) writes: > struct of_stuff { > char *name > float value; > float another; > int counter; > } > > stuff[20][30] = { > { > "joe", 1, 0, 12, > [...] > This works fine on VMS 4.5 (VMS C - 4.?) and on my PC using MS C 3.0. > However, when I tried it on a vax 11/780 running 4.3BSD and a Sun > workstation running whatever they call Unix (the latest 3.0 I > believe), I got an error. The error was repeated 4 times for each > line that has a name in it (like "joe"), the error said I was missing > a }. (or something to that effect.) I copied the code from your posting and tried compiling it on 4.3. It produced three errors for each initialization line, the error saying "} expected". This leads me to believe that you were actually trying to compile the above code. This is important because what you posted is missing a semicolon on the first element of the structure!! In fact, the *first* error message the compiler produced complained about this. Generally, you should fix the first error first. Then run through the rest of the errors, fixing any that seem reasonable and forgetting about any that don't seem to make sense. This is because, as in this case, one error can cause may others - this is termed "floodgating". Bright note: you do have the initialization syntax right. (I could argue about the placement of the braces, but style has nothing to do with the *correctness* of the code.) der Mouse Smart mailers: mouse@mcgill-vision.uucp USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!musocs!mcgill-vision!mouse think!mosart!mcgill-vision!mouse ARPAnet: think!mosart!mcgill-vision!mouse@harvard.harvard.edu
meissner@dg_rtp.UUCP (03/23/87)
In article <340@slovax.UUCP> michael@slovax.UUCP (Michael Longe) writes: (original example deleted, you've seen it before) > .... It compiled okay with the addition of another level of > matching {}: > > stuff[20][30] = { > { > {"joe", 1, 0, 12}, > {"fred", 1, 0, 13}, > {"carol",1, 0, 4} } > } > > K&R p. 124 says, for a particular example, "... It would be more precise > to enclose initilizers for each 'row' or structure in braces, ... but the > inner braces are not necessary when the initializers are simple variables > or character strings, and when all are present." > > Apparently some compilers prefer the inner braces. It doesn't hurt to have > them in either case. The technical reason the compilers are spilt on this issue seems to be the way the compilers are implemented. Compilers implemented via top-down recursive descent (ie, the original Ritchie PDP-11 C compiler, MANX, etc.) will accept the minimal braces, wheras bottom up LALR based compilers (the Johnson PCC compiler in particular) have difficulty with this. The draft ANSI standard says it is implementation defined what happens if you have left some intermediate level of braces off. -- Michael Meissner, Data General Uucp: ...mcnc!rti-sel!dg_rtp!meissner It is 11pm, do you know what your sendmail and uucico are doing?
msb@sq.UUCP (03/26/87)
> The draft ANSI standard says it is implementation defined what > happens if you have left some intermediate level of braces off. Nope, at least not the October 1986 (public comment) draft. Some earlier ones said only that this would be resolved in a later draft; perhaps still earlier ones said it was implementation dependent. a From section 3.5.6, page 62 (lines 3-17): # An array of characters may be initialized by a string literal, # optionally enclosed in braces. Successive characters of the # string literal (including the terminating null character if there # is room or if no size for the array is specified) initialize the # members of the array. # # Otherwise, the initializer for an object that has aggregate type # shall be a brace-enclosed list of initializers for the members of # the aggregate, written in increasing subscript or member order. # # If the aggregate contains members that are aggregates, the rules # apply recursively to the subaggregates. If the initializer of a # subaggregate begins with a left brace, the succeeding initializers # initialize the members of the subaggregate. Otherwise, only enough # initializers from the list are taken to account for the members of # the first subaggregate; any remaining initializers are left to # initialize the next member of the subaggregate of which the current # aggregate is a part. # # If there are fewer initializers in a list than there are members of # an aggregate, the remainder of the aggregate shall be initialized # implicitly the same as objects that have static duration. I think the above is almost incomprehensible without careful study, but the example at lines 42-25 of the same page makes things clear: # struct { int a[3], b; } w[] = { { 1 }, 2 }; # # is a definition with a partly bracketed initialization, which is # not recommended programming practice. It defines an array with two # member structures: w[0].a[0] is 1 and w[1].a[0] is 2; all the other # elements are zero. That is, the above is equivalent to: struct { ... } w[] = { { { 1 } }, { { 2 } } }; and therefore to struct { ... } w[] = { {{1,0,0}, 0}, {{2,0,0}, 0} }; Mark Brader, utzoo!sq!msb C unions never strike!