[comp.lang.c] Need macro to get offset within a structure

richardm@runx.oz.au (Richard Murnane) (02/17/91)

Hi all,
Does anybody know a decent macro to find the offset of an element
in a structure, e.g. if I have a structure

typedef struct ABC
{
	int a;
	char b[5];
	float c;
} ABC_STRUCT;

I need a macro hich will let me say OFFSET(ABC_STRUCT,c), which will
give me the offset of the float in the above structure.

I have tried something like this:

#define OFFSET(s,e)  & (((s *) NULL)->e)
and the above followed by  -NULL to force the compiler to evaluate the
macro as the difference of two addresses (and to avoid problems with
different memory models).

Microsoft C 5.1 chokes on the macro, when I try to initialise elements
of a table with such an expression (although if I remove the "&", as I
might to evaluate the address of the array b in the structure, the
compiler accepts it. However, I'm looking for something that will work
for the general case).

I vaguely remember doing something like this for a brain-dead Intermetrics
compiler a few years ago, so it must be possible :-) I just don't remember
how!
Thanks in advance,
- Richard

-- 
Richard P. Murnane                       "Let's just be friends." ?
Internet: richardm@runxtsa.runx.oz       - Just Say No.
Packet Radio: VK2JRM @ VK2OP.NSW.AUS.OC

enag@ifi.uio.no (Erik Naggum) (02/19/91)

In article <1991Feb16.232713.6001@runx.oz.au>, Richard Murnane writes:

> Does anybody know a decent macro to find the offset of an element
> in a structure

I snatched this from /local/lib/gcc-include/stddef.h.

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

This works like a charm on a vast number of compilers I've used.

--
[Erik Naggum]					     <enag@ifi.uio.no>
Naggum Software, Oslo, Norway			   <erik@naggum.uu.no>

gwyn@smoke.brl.mil (Doug Gwyn) (02/20/91)

In article <ENAG.91Feb19131201@holmenkollen.ifi.uio.no> enag@ifi.uio.no (Erik Naggum) writes:
>#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

What I would recommend is to key on __STDC__, #including <stddef.h>
in a Standard C environment and using a definition like that one in
other environments.  It should work in most non-standard C environments
(but not all of them!).

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (02/21/91)

In article <ENAG.91Feb19131201@holmenkollen.ifi.uio.no>, enag@ifi.uio.no (Erik Naggum) writes:
> I snatched this from /local/lib/gcc-include/stddef.h.
> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> This works like a charm on a vast number of compilers I've used.

offsetof() being a required part of ANSI C (if you use the right header),
it's clearly the right interface.  You'll want an #if __STDC__ so that you
get the "official" version when it's there, as the cast of zero is not
portable.
-- 
Professional programming is paranoid programming

bengsig@dk.oracle.com (Bjorn Engsig) (02/21/91)

In article <1991Feb16.232713.6001@runx.oz.au>, Richard Murnane writes:
|Does anybody know a decent macro to find the offset of an element
|in a structure

And in article <ENAG.91Feb19131201@holmenkollen.ifi.uio.no> enag@ifi.uio.no
(Erik Naggum) replied:
|#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|This works like a charm on a vast number of compilers I've used.

Actually, ANSI C includes an offsetof macro in <stddef.h>.  And please do
not enter the usual discussion of wheather the macro definition above is
valid ANSI C or not.  The rationale of the ANSI C will fill you in with the
details of this.
-- 
Bjorn Engsig, ORACLE Corporation, E-mail: bengsig@oracle.com, bengsig@oracle.nl

            "Stepping in others footsteps, doesn't bring you ahead"

dcurtis@crc.ac.uk (Dr. David Curtis) (02/21/91)

In article <1991Feb16.232713.6001@runx.oz.au> richardm@runx.oz.au (Richard Murnane) writes:
>Hi all,
>Does anybody know a decent macro to find the offset of an element
>in a structure?

How about:

#define offset(str,el) ((char*) &((str*)NULL)->el - (char*) NULL)