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