🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #12255

Determining structure field offsets

#12255
From: Jeff Kelley
Date: Mon, 17 Apr 1989 13:54
62 lines
2620 bytes
What's the best way to determine the offset of a field of
a structure?  For example, if I have:
	struct foobar {
		int foo;
		int bar;
	};
how can I determine the offset of the 'bar' field in a
manner independent of preceding fields?  My initial
attempt was to use a macro of the form:
	#define STRUCT_OFFSET(structure, field) \
		((int)&((structure *)0)->field)
used like:
	offset = STRUCT_OFFSET(struct foobar, bar);

However, compiling with Lattice C 5.02 produces the Error
"Invalid structure reference" for this statement.  If the
0 in the macro is changed to something else, though,
such as a 1, no error is produced.  Of course, we have to
subtract 1 to compensate, so we get:
	#define KLUDGE 1	
	#define STRUCT_OFFSET(structure, field) \
		((int)&(((structure *)KLUDGE)->field)-KLUDGE)

This would be satisfactory (although I still don't
understand why 0 doesn't work) except that the compiler
produces pretty bad code, something like:
	movea.w	#1,a0
	lea	4(a0),a1
	move.l	a1,d0
	move.l	d0,d7		*
	subq.l	#1,d7
	move.l	d7,d0		*

(The two '*'ed statements are effectively eliminated by
 the 'global optimizer'.)

It seems to be a rather poor way of doing a
	moveq.l	#4,d0
which is generated by the GNU C compiler, at least when
KLUDGE is 0 (which doesn't produce an error with GNU C).
Couldn't the compiler do some expression tree analysis
and reduction?  Seeing code like this makes me want to
quit working as a programmer and take up fish-farming
in Alaska :-)

For an example of how this facility might be used, consider
a memory allocation scheme which records the size of the
memory allocated in the first longword of the allocated
block, then returns a pointer to the remainder to the user.
i.e. struct Block { long size; char user_area };
When the user calls 'free(block)' or whatever, in order to
find the block size you need to subtract the offset of
the user_area field from the pointer the user gives you.
Subtracting	'sizeof(long) ' or 'sizeof(block->size)'
doesn't cut it (in my opinion) because it doesn't track
changes to the structure.

Any and all help is appreciated.
--
Jeff Kelley    National Research Council of Canada, Ottawa
   uunet!watmath!watcgl!jvkelley  	tel:   (613) 990-5924
Technical Details
Message-ID: <9270@watcgl.waterloo.edu>
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!watmath!watcgl!jvkelley

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!watmath!watcgl!jvkelley
From: jvkelley@watcgl.waterloo.edu (Jeff Kelley)
Newsgroups: comp.sys.amiga.tech
Subject: Determining structure field offsets
Keywords: Lattice C 5.02
Message-ID: <9270@watcgl.waterloo.edu>
Date: 17 Apr 89 13:54:06 GMT
Distribution: comp
Organization: U of Waterloo, Ontario
Lines: 62