Article View: comp.sys.amiga.tech
Article #12255Determining structure field offsets
From: Jeff Kelley
Date: Mon, 17 Apr 1989 13:54
Date: Mon, 17 Apr 1989 13:54
62 lines
2620 bytes
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!jvkelleyShow 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