Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!rutgers!dayton!meccts!viper!john From: john@viper.UUCP Newsgroups: comp.lang.c Subject: Re: zero length array Message-ID: <563@viper.UUCP> Date: Sat, 21-Feb-87 14:57:32 EST Article-I.D.: viper.563 Posted: Sat Feb 21 14:57:32 1987 Date-Received: Sun, 22-Feb-87 05:38:39 EST References: <4498@brl-adm.ARPA> <1987Feb19.134433.737@sq.uucp> Reply-To: john@viper.UUCP (John Stanley) Organization: DynaSoft Systems Lines: 37 In article <1987Feb19.134433.737@sq.uucp> msb@sq.UUCP (Mark Brader) writes: > >You need an actual object of the struct type, say tmp; and then, of course, >you can say: > > (char *) &tmp.any_field - (char *) &tmp > >In the current ANSI draft, there is a predefined macro "offsetof" which >does something like this for you without needing you to specify an object. > >However, I've never met a case where this operation was really necessary. >Usually the job can be done more comprehensibly with unions. > >Mark Brader, utzoo!sq!msb C unions never strike! Mark, I agree with you that the other construct is poor, that the one you gave is considerably better, but I disagree with you on the subject of unions. I've had experience with many (far -too- many) compilers that have multiple bugs in the handleing of unions. For portability, it's best to -not- use unions in general, and in this instance especialy. (Unions are in many cases totaly non-portable across systems with different byte order rules. And there is more than one compiler that fails to poperly handle increment/decrement if you have a union consisting of several pointer types...) The best solution I've come up with is as follows: #define ANOFFSET (int)(((char*)&tmp.any_field) - ((char*)&tmp)) The construct you created will be typed as an int on some systems and as a long on others. This means you can't portably use it in a parameter list. Adding the (int) (or (long)) cast at the beginning solves this portability problem. ---- John Stanley (john@viper.UUCP) - DynaSoft Systems