On 08/16/2010 02:21 PM, Eric Blake wrote: > * tests/test-stddef.c: Add tests for offsetof. > > Signed-off-by: Eric Blake <ebl...@redhat.com> > --- > > I was about to push this, so we can detect any gotchas with using > offsetof according to POSIX. Then I decided to test first. > > And the first loser is Solaris' /usr/bin/cc: > "../../gltests/test-stddef.c", line 44: syntax error before or at: & > "../../gltests/test-stddef.c", line 44: warning: syntax requires ";" after > last struct/union member > "../../gltests/test-stddef.c", line 44: zero-sized struct/union > "../../gltests/test-stddef.c", line 44: cannot recover from previous errors > cc: acomp failed for ../../gltests/test-stddef.c > > Adding "redundant" parens to the sizeof(offsetof()) call fixed the > it for that compiler. Sure enough, /usr/include/iso/stddef_iso.h has: > > #define offsetof(s, m) (std::size_t)(&(((s *)0)->m))
The problem is how do we provide a working offsetof replacement, given that there is no way using standard C89 or C++ constructs to do it? All implementations either use something like this which abuses undefined behavior within the standard but works without warning for that compiler: #define offsetof(__a,__b) ((size_t)(&(((__a*)0)->__b))) or do something like gcc in providing a hidden builtin that does the right thing: #define offsetof(__a,__b) __builtin_offsetof(__a,__b) Maybe the thing is to do a case-by-case implementation that provides implementations that work with the compilers we know about, but issues #error for remaining compilers; the fix should be to use whatever the platform's <stddef.h> does. For that matter, we could compute the correct offsetof expression at configure time, for any given compiler, by pre-processing a dummy file and running that output through the Makefile.am sed snippet that we stick into our replacement stddef.h. I guess I'll play with that approach. -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature