Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site umcp-cs.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!qantel!dual!lll-crg!seismo!umcp-cs!chris
From: chris@umcp-cs.UUCP (Chris Torek)
Newsgroups: net.lang.c
Subject: Re: handy.h: macro
Message-ID: <1562@umcp-cs.UUCP>
Date: Thu, 12-Sep-85 15:56:20 EDT
Article-I.D.: umcp-cs.1562
Posted: Thu Sep 12 15:56:20 1985
Date-Received: Sun, 15-Sep-85 10:01:28 EDT
References: <1153@wucs.UUCP>
Organization: U of Maryland, Computer Science Dept., College Park, MD
Lines: 41
Keywords: offsets within structures

In article <1153@wucs.UUCP> tp@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@umcp-cs		ARPA:	chris@maryland