[comp.std.c] The offsetof macro

walter@hpcllca.HP.COM (Walter Murray) (08/27/88)

I think this may have been discussed a few months ago in comp.lang.c.
If so, would someone please mail or post the consensus that was
reached?

The offsetof macro is supposed to expand to an integral constant
expression.  There are strict rules about the operands and casts
that can be used in an integral constant expression, so, for
example, an expression containing "(type *)0" wouldn't be legal.
Using such an illegal expression in a place where an integral
constant expression is required, such as a case label expression,
would violate a constraint and would seemingly require a diagnostic
to be produced.

So what is a valid way to define offsetof?

Thanks

Walter Murray
All opinions expressed are my own

bill@proxftl.UUCP (T. William Wells) (08/29/88)

In article <16490006@hpcllca.HP.COM> walter@hpcllca.HP.COM (Walter Murray) writes:
: I think this may have been discussed a few months ago in comp.lang.c.
: If so, would someone please mail or post the consensus that was
: reached?
:
: The offsetof macro is supposed to expand to an integral constant
: expression.  There are strict rules about the operands and casts
: that can be used in an integral constant expression, so, for
: example, an expression containing "(type *)0" wouldn't be legal.
: Using such an illegal expression in a place where an integral
: constant expression is required, such as a case label expression,
: would violate a constraint and would seemingly require a diagnostic
: to be produced.
:
: So what is a valid way to define offsetof?

There isn't any portable way that I can think of.  I wouldn't be
surprised if that is why it is defined in a header file where the
compiler is free to define it any way it wants.  For example, it
could be defined as:

#define offsetof(type,mem) __offsetof_kludge(type,mem)

and, could then treat __offsetof_kludge somewhat as it might
treat sizeof.

---
Bill
novavax!proxftl!bill

gwyn@smoke.ARPA (Doug Gwyn ) (08/31/88)

In article <16490006@hpcllca.HP.COM> walter@hpcllca.HP.COM (Walter Murray) writes:
>So what is a valid way to define offsetof?

There is no portable way to #define an offsetof() macro in C.
The usual method you already know will nonetheless work on a
large number of implementations.  Others may have to use a
compiler intrinsic for this.

karl@haddock.ima.isc.com (Karl Heuer) (09/08/88)

In article <8402@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) writes:
>In article <16490006@hpcllca.HP.COM> walter@hpcllca.HP.COM (Walter Murray) writes:
>>So what is a valid way to define offsetof?
>
>There is no portable way to #define an offsetof() macro in C.
>The usual method you already know will nonetheless work on a
>large number of implementations.

I don't think the question was about a *portable* way to define it.  The
original poster was noting that the "usual method" involves a macro that
involves some trickery with a null pointer constant, and claimed that since
this violates a constraint, a conforming compiler is required to diagnose an
error.  This would seem to imply that offsetof() *must* be defined as a
compiler builtin, even on well-behaved architectures.

But I don't believe this to be the case.  The relevant portion of 3.4 is under
"Semantics", not "Constraints", and says "Cast operators in an integral
constant expression shall only convert arithmetic types to integral types".  A
violation of a "shall" clause outside a constraint is undefined behavior,
which does not require diagnosis.  Thus, a conforming compiler can do the
right thing with the null pointer hack, and use it in offsetof().

If there really is a violated constraint involved, could someone post the
reference?

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

walter@hpcllca.HP.COM (Walter Murray) (09/09/88)

Karl Heuer writes:

>In article <8402@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) writes:
>>In article <16490006@hpcllca.HP.COM> walter@hpcllca.HP.COM (Walter Murray) writes:
>>>So what is a valid way to define offsetof?
>>
>>There is no portable way to #define an offsetof() macro in C.
>>The usual method you already know will nonetheless work on a
>>large number of implementations.
>
>I don't think the question was about a *portable* way to define it.  The
>original poster was noting that the "usual method" involves a macro that
>involves some trickery with a null pointer constant, and claimed that since
>this violates a constraint, a conforming compiler is required to diagnose an
>error.  This would seem to imply that offsetof() *must* be defined as a
>compiler builtin, even on well-behaved architectures.
>
>But I don't believe this to be the case.  The relevant portion of 3.4 is under
>"Semantics", not "Constraints", and says "Cast operators in an integral
>constant expression shall only convert arithmetic types to integral types".  A
>violation of a "shall" clause outside a constraint is undefined behavior,
>which does not require diagnosis.  Thus, a conforming compiler can do the
>right thing with the null pointer hack, and use it in offsetof().
>
>If there really is a violated constraint involved, could someone post the
>reference?
>
>Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
>----------

My thinking is that 3.4 defines the term "integral constant expression".
It seems to me that it doesn't matter that that definition is in the
Semantics section:  An expression which uses the null pointer hack
is, by definition, NOT an "integral constant expression".

Now consider a switch statement.  According to a CONSTRAINT in 3.6.4.2,
"The expression of each case label shall be an integral constant
expression."  An expression which uses the null pointer hack is
not an "integral constant expression", and therefore would violate
this constraint and require a diagnostic, would it not?

Is a conforming implementation free to change its definition of
"integral constant expression" on the grounds that the definition
appears under Semantics instead of Constraints?  

Walter Murray