structure element offsets

David Messer dave at viper.UUCP
Fri Dec 5 18:50:46 AEST 1986


In article <3695 at watmath.UUCP> rbutterworth at watmath.UUCP (Ray Butterworth) writes:
 >In article <386 at viper.UUCP>, dave at viper.UUCP (David Messer) writes:
 >> A simpiler definition of the OFFSET macro is the following:
 >> 	#define OFFSET(mos)  ((long)(&(((char *)0)->mos)))
 >> This will produce a proper offset on almost all machines.  (But
 >> not all, some machines have different formats to pointers to
 >> different types.  Also, this macro assumes that (long)((char *)0) == 0L.)
 >
 >"on almost all machines" means it is totally wrong on some machines.
 >What is the point of making something simpler if it's going to be
 >wrong?
 >How about "#define OFFSET(mos) 4"?  That's really simple and will
 >also be correct sometimes.
 >What is the point of bothering to assume that (long)(char*)0 is 0?
 >Why not simply subtract whatever (char*)0 really is from the other
 >pointer and always get the correct answer on all machines (as I
 >originally suggested)?
 >
 >On any one machine, the simplest and most complicated forms of this
 >macro will generate exactly the same code (assuming both are correct).
 >What is it you think you are gaining by "simplifying" it?
 >

Because your solution doesn't work all the time either.  There are
some machines in which pointers to different types are unrelated
in format.  In other words a cast such as (type1 *)(type2 *)x
will not always give a meaningful answer.  According to K&R all
that is required is that (type *)(long *)x == x.

Since one cannot make a macro that will work on a arbitrary
machine, other considerations apply when writing code such as
this.  For instance you assume that (x - (char *)0) will compile
to the same code as (x).  I have known some brain-damaged compilers
to actually generate code for the cast and the subtract.  There are
no machines to my knowledge where (long)(char *)0 != 0L and
other problems (such as casting of pointers) don't prevent
the offset macro to work.
 >
 >Besides, what makes you think you can get away with ((char*)0)->mos?
 >Compilers which accept this (e.g. BSD) give this warning:
 >"xxx.c", line 15: warning: struct/union or struct/union pointer required
 >And if two structures should happen to have members with the same name:
 >"xxx.c", line 15: nonunique name demands struct/union or struct/union pointer
I will conceed that you have a point here, however, for good or ill,
C has been defined such that all members-of-structures share the
same name-space.  If you have a compiler which gives you these
helpful hints, it is an easy matter to add a structure name
parameter to the macro.
-- 
Disclaimer:                       | David Messer 
I'm always right and I never lie. | Software Consultant 
My company knows this and agrees  | UUCP:  ihnp4!quest!viper!dave 
with everything I say.            |        ihnp4!meccts!viper!dave



More information about the Comp.lang.c mailing list