[svlug] Structure Field Offset Measurement
Chris Waters
xtifr at dsp.net
Sat Jan 6 14:54:01 PST 2001
On Sat, Jan 06, 2001 at 01:25:37PM -0800, Karen Shaeffer wrote:
> Now here, I believe J C was referring to:
> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> which is the implmentation specific realization of the standard's
> concisely defined behavior for the MACRO. And you guys are specifically
> stating that the linux/gcc X86 implementation of this MACRO is not well
> thought out or somehow defective?
No, not at all. The macro is contained in a standard header, and
therefore does not need to follow the constraints of the standard as
long as it provides the behavior that the standard requires.
Remember that FSF code uses configure. If glibc were ported to a
platform where this trick didn't work, it would be easy enough to test
for this and substitute other code here, on that platform.
> > The magic phrase is "undefined behavior". There is no "as expected"
> > behavior here, in terms of the C standard. In fact, I believe that
> > the mere fact that this involves a memory reference outside of any
> > memory allocated by the system means that the behavior is completely
> > undefined (it is allowed to crash, format your drive, or start
> > /usr/games/rogue).
> This is where you lose me. My interpretation of that implementation specific
> MACRO is that it is not a memory reference at all. It is a compile-time
> evaluation of a known expression.
No. Constant-folding is not a requirement of the standard, even
though most decent compilers will do it (unless specifically directed
not to). Furthermore, this particular expression involves address
arithmetic, and therefore *must* be evaluated at run-time on some
machines.
Another point you seem to keep missing is that the standard explicitly
states that a literal (or constant) value of zero is MAGIC when
evaluated in a pointer context, and NEED NOT RESULT IN AN
ALL-BITS-ZERO VALUE!
Consider this:
int zero = 0;
if ( (char *)zero != (char *)0)
printf ("zero is not 0.\n");
This code fragment is allowed to produce output by the C standard!
As is this one:
char *zptr;
memset (&zptr, 0, sizeof (char *));
if (zptr != (char *)0)
printf ("0 is not all-bits-zero\n");
I strongly recommend that you get and study the C faq, as many of
these things are not at all intuitive.
cheers
--
Chris Waters | Pneumonoultra- osis is too long
xtifr at debian.org | microscopicsilico- to fit into a single
or xtifr at dsp.net | volcaniconi- standalone haiku
More information about the svlug
mailing list