Dizio@udel.edu (02/17/87)
Not to nit pick but is it always true that within the structure
struct LINE {
struct header_junk hj;
char text[32768];
} ;
'text' falls immediately after 'hj'? If not I would be wary
about mallocing sizeof(header_junk) + length.
II.
Is the following a portable way of finding out where a field
within a structure is located?
& (((struct any_struct_tag *) 0)->any_field)
Dave DiZio
msb@sq.UUCP (02/19/87)
Dizio@udel.edu writes: > Not to nit pick but is it always true that within the structure > > struct LINE { struct header_junk hj; char text[32768]; } ; > > 'text' falls immediately after 'hj'? It isn't guaranteed. A compiler is allowed to leave space in there according to the type of the following member, i.e., char[] here. However, any extra space required for alignment of the inner struct will be counted as part of that struct. It seems most unlikely that "char[]" could have alignment requirements more strict than a struct, but there is nothing forbidding it. > Is the following a portable way of finding out where a field > within a structure is located? > & (((struct any_struct_tag *) 0)->any_field) No. When 0 is converted to pointer type (remember, a cast is a conversion), all you know is that the resulting pointer doesn't point to a valid object. In this case there are certainly machines where it's not a numeric 0. 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!
john@viper.UUCP (02/21/87)
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
woods@gpu.utcs.toronto.edu (02/26/87)
In article <4498@brl-adm.ARPA> Dizio@udel.edu writes: > Is the following a portable way of finding out where a field >within a structure is located? > > & (((struct any_struct_tag *) 0)->any_field) Not that I know of, though the expression without "&" is usefull in sizeof(). Some compilers will refuse to cast NULL, specifically Lattice C up to 2.15(?) As far as I know all Unix compilers will cast NULL. You might want to cast one(1) instead. Lattice will accept this. Greg Woods.
jpn@teddy.UUCP (02/27/87)
>> Is the following a portable way of finding out where a field >>within a structure is located? >> >> & (((struct any_struct_tag *) 0)->any_field) > >Some compilers will refuse to cast NULL, specifically Lattice C up to 2.15(?) >As far as I know all Unix compilers will cast NULL. If true, then Lattice is seriously broken. Are you saying that I can't say time ((long *) 0) in Lattice C? Or execl(pgmname, arg0, arg1, (char *) 0)? If it can't do these things, then it isn't a C compiler!! . . . (I hate the 2.11 inews) . .
woods@gpu.utcs.toronto.edu (02/28/87)
I guess we are getting a little off topic here, but anyway... I haven't used Lattice in a long time (and I'd rather not), but as far as I can remember, the casting of zero (0) works, except when used to reference a structure member, especially in a sizeof() expression: sizeof(((struct xyzzy *) 0)->member) My original article may not have made this clear. Greg Woods.
meissner@dg_rtp.UUCP (Michael Meissner) (03/06/87)
In article <1987Feb25.201816.29714@gpu.utcs.toronto.edu> woods@gpu.utcs.UUCP (Greg Woods) writes: > In article <4498@brl-adm.ARPA> Dizio@udel.edu writes: > > Is the following a portable way of finding out where a field > >within a structure is located? > > > > & (((struct any_struct_tag *) 0)->any_field) > > Not that I know of, though the expression without "&" is usefull in sizeof(). > > Some compilers will refuse to cast NULL, specifically Lattice C up to 2.15(?) > As far as I know all Unix compilers will cast NULL. > > You might want to cast one(1) instead. Lattice will accept this. > > Greg Woods. I believe the harris compiler also has problems with this. Also any implementation which does not produce all zero bits for integer 0 -> pointer (or vica versa) would have problems with this. That's why offsetof was created in ANSI. -- Michael Meissner, Data General Uucp: ...mcnc!rti-sel!dg_rtp!meissner It is 11pm, do you know what your sendmail and uucico are doing?