handy.h: macro

Chris Torek chris at umcp-cs.UUCP
Fri Sep 13 05:56:20 AEST 1985


In article <1153 at wucs.UUCP> tp at wucs.UUCP (tom thumbs) writes:

> The macro OFFSETV is good for finding the offset of a
> certain variable within a structure. [...]

> #define OFFSETV(X, Y)	( (int) &((struct X *)0)-> Y )

> I believe that credit for coming up with these belongs to
> Brian Thomas of AT&T (ihnp4!we53!bmt).

Actually, that technique has been used in 4BSD for quite a while.
/sys/vax/genassym.c declares some pointers to structures, puts
zeros in them, and uses addresses of their fields to print out code
suitable for input to the assembler to define the offsets to fields
that are required by the assembly-coded portion of the kernel.
(Later, if the definitions of those structures are changed, no
code need be changed.)

I might point out (as Guy is likely in the process of doing right
now as well) that this, like so much other useful code, is (alas!)
not portable.  Consider a hypothetical byte-addressable 32 bit
machine where the ``null `struct foo' pointer'' has a bit pattern
whose value is 0xc0000000 when taken as a ``int''.  Then the compiler
will cast 0 to ``struct foo *'', yeilding 0xc0000000, add to that
the offset for the given field, and pun that into an integer, giving
results like 0xc0000004.

(What C compiler would do this?  Well, a Vax compiler just might.
Zero *is* a legal address, after all, and 0xc0000000 is not....)

On such a machine,

#define OFFSETV(x,y)	\
	((int) &((struct x *)0)->y - (int) ((struct x *)0))

would suffice to eliminate the offset; but this might fail on
a machine that was not byte addressable.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris at maryland



More information about the Comp.lang.c mailing list