Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!shadooby!accuvax.nwu.edu!tank!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Using data types before they are declared. Message-ID: <18137@mimsy.UUCP> Date: 19 Jun 89 06:54:14 GMT References: <10268@watcgl.waterloo.edu> <548@corona.pb> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 76 In article <548@corona.pb> db2@pbinfo.UUCP (Vorl. Informationssysteme) suggests trying the following code: >union Fred { > int Number; > struct _el_str *Node; >}; > >struct _el_str { > int Info; > Fred Name; >}; >typedef struct _el_str *element; > >I am practising this in my own programs very often. I doubt it: as written, it will not compile. (It will in C++, however.) The best approach is to ignore `typedef' completely, give all structures and unions tags, and add typedefs afterward if you wish. Thus: union Fred { int Number; struct _el_str *Node; }; struct _el_str { int Info; union Fred Name; }; (The difference between this and the first 9 lines of code quoted above is the addition of one `union' keyword.) Then, if necessary: typedef union Fred { int Number; struct _el_str *Node; /* no synonyms available */ } Fred; /* `Fred' is now a synonym for `union Fred' */ typedef struct _el_str { int Info; union Fred Name; /* this can now be abbreviated */ } *element; /* `element' is now a synonym for `struct _el_str *' */ Other approaches are possible, but this one always works: Avoid the abbreviation until it has been defined, and always use a structure or union tag so that there *is* an unabbreviated form. At worst, you will invent some tags you never use. Incidentally, I happen to like the practise of naming structure and union elements in a `type-describing' manner: struct glumph { char *g_name; /* name of this glumph */ int g_mass; /* mass of this glumph, in kg */ short g_halflife; /* biodegredation halflife, years */ short g_cost; /* price in cents per kg */ }; If I then spot a line like p->g_mass somewhere, I have a clue (the `g_' element prefix) that `p' is an object of type `pointer to struct glumph'. (This practise arose from pre-V7 C's approach of putting all structure elements/offsets in a single global table, making unions unnecessary, but forcing prefixes to guarantee uniqueness, and weakening type-checking. The prefixes turned out to be convenient, and were included in new structures in V7 and BSD.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris