Topic: offsetof and POD structs


Author: Daniel Villeneuve <danielv@crt.umontreal.ca>
Date: 1999/02/02
Raw View
In trying to compile C code with a C++ compiler, I got errors from a
fragment resembling:

#include <stddef.h>
int i =3D offsetof(struct { char a; double b; }, b);

The error (from a C++ point of view) is that this expression creates a
new type in a cast expression.  But the cast expression comes from the
(usual) implementation of offsetof(T, m), which implies casting 0 into a
pointer of type T and then converting the address of ((T *)0)->m into
the desired result.

In section 18.1 of CD2, it is written: ``The macro offsetof accepts a
restricted set of type arguments in this International Standard. type
shall be a POD structure or a POD union (9).''  In the example above, T
is clearly a POD structure.

So, can I view this as a bug in the implementation of offsetof in
stddef.h?

Could the implementors argue that I should have included <cstddef>
instead (which in this case would cause the same problem to occur, since
the latter is just a wrapper for the former on my platform)?

Or is it really a bug in my code?

--=20
Daniel Villeneuve                      =20
Graduate student in Operations Research=20
GERAD/Math=E9matiques Appliqu=E9es         =20
=C9cole Polytechnique de Montr=E9al
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1999/02/03
Raw View
Daniel Villeneuve <danielv@crt.umontreal.ca> writes:

>In trying to compile C code with a C++ compiler, I got errors from a
>fragment resembling:

>#include <stddef.h>
>int i = offsetof(struct { char a; double b; }, b);

>The error (from a C++ point of view) is that this expression creates a
>new type in a cast expression.  But the cast expression comes from the
>(usual) implementation of offsetof(T, m), which implies casting 0 into a
>pointer of type T and then converting the address of ((T *)0)->m into
>the desired result.

>In section 18.1 of CD2, it is written: ``The macro offsetof accepts a
>restricted set of type arguments in this International Standard. type
>shall be a POD structure or a POD union (9).''  In the example above, T
>is clearly a POD structure.

Quoting details from CD2 is risky, since CD2 has many detailed
errors, but in this case the final standard says the same thing.

>So, can I view this as a bug in the implementation of offsetof in
>stddef.h?

In a sense, it is a bug in the implementation, because the
requirements on offsetof do not forbid defining a type.

But there is no ordinarily no good reason to define a type in
offsetof. After all, presumably you want the offset to be applied
to an object of that type, so you will have to define the type
someplace else too. That is, the use of the type appears in at
least two places: an object definition, and the offset computation.
On that basis alone, you should have just one definition for the
type and give it a name.

You can try to beat up the vendor about rejecting your code, but
I suspect that
1. this "bug" will be common to most, if not all, implementations, and
2. a Defect Report might be filed on the standard, resulting in a
   change to the language definition. In that case, the bug moves
   from the compiler to your code. :-)

It's simpler all around to write
    struct S { char a; double b; }; // in a header
    ...
    offsetof(S, b);
Then the code works everywhere, and doesn't suffer from the
problems inherent in having two definitions for what is supposed
to be one type.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]