Date: Mon, 4 Oct 2004 08:10:41 -0500 (CDT) From: Patrick Hartling <patrick@137.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: misc/72307: offsetof() macro emits non-compliant code for C++ Message-ID: <20041004131041.B3AE53A1D4@dsl.80.187.networkiowa.com> Resent-Message-ID: <200410041320.i94DKLn0050867@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 72307 >Category: misc >Synopsis: offsetof() macro emits non-compliant code for C++ >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Oct 04 13:20:21 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Patrick Hartling >Release: FreeBSD 5.3-BETA5 i386 >Organization: >Environment: System: FreeBSD dsl.80.187.networkiowa.com 5.3-BETA5 FreeBSD 5.3-BETA5 #59: Sat Sep 25 10:17:05 CDT 2004 root@dsl.80.187.networkiowa.com:/usr/obj/usr/src/sys/HOME i386 This problem applies to all FreeBSD 5.3 beta releases and to 6.0-current. >Description: The offsetof() macro defined in /usr/includestddef.h emits code that violates the C++ standard depending upon the context of its use (see Section 5.19, Paragraph 1 of the ISO C++ Standard). With the import of GCC 3.4.2, this is a serious problem because the C++ compiler is now much more strict in its enforcement of the C++ standard. The included code fails to compile with GCC 3.4.2 in the base system with the following errors: const-exp.cpp:14: error: a casts to a type other than an integral or enumeration type cannot appear in a constant-expression const-exp.cpp:14: error: '->' cannot appear in a constant-expression const-exp.cpp:14: error: `&' cannot appear in a constant-expression GCC 3.4.2 built from the Ports Collection (gcc-3.4.2_20040827) builds the code without problem. I believe that this is because this GCC version gets offsetof() from its own stddef.h, which has a C++-friendly variant. The following code demonstrates the problem. It is adapated from code used by the Boost.Python library (http://www.boost.org/libs/python/) found in the header boost/python/object/instance.hpp (the struct additional_instance_size at the end of the file). This offsetof() macro breaks compiling of Boost.Python from Boost 1.31.0 and from the upcoming Boost 1.32.0 code base. It could affect other Boost libraries as well as other C++ code in general. #include <stdlib.h> #include <stddef.h> struct instance_char { union { char bytes[sizeof(char)]; } storage; }; struct myType { static const size_t value = offsetof(instance_char, storage); }; void f() { myType t; } >How-To-Repeat: Compile the above code using GCC 3.4.2 from the base system: % g++ -c const-exp.cpp >Fix: Fixing this problem should be as easy as using the offsetof() definition from the GCC 3.4.2 stddef.h: /* Offset of member MEMBER in a struct of type TYPE. */ #ifndef __cplusplus #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #else /* The cast to "char &" below avoids problems with user-defined "operator &", which can appear in a POD type. */ #define offsetof(TYPE, MEMBER) \ (__offsetof__ (reinterpret_cast <size_t> \ (&reinterpret_cast <const volatile char &> \ (static_cast<TYPE *> (0)->MEMBER)))) #endif /* C++ */ The ease of fixing this may not be so simple if there are copyright issues... >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041004131041.B3AE53A1D4>