gnu/76069: FreeBSD's definition of offsetof isn't good for C++
Dmitrij Tejblum
tejblum at yandex-team.ru
Mon Jan 10 11:50:05 PST 2005
>Number: 76069
>Category: gnu
>Synopsis: FreeBSD's definition of offsetof isn't good for C++
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Jan 10 19:50:04 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Dmitrij Tejblum
>Release: FreeBSD 5.3-STABLE i386
>Organization:
>Environment:
System: FreeBSD developer.yandex.ru 5.3-STABLE FreeBSD 5.3-STABLE #11: Sun Dec 12 06:00:53 MSK 2004 root at developer.yandex.ru:/opt/obj/usr/src/sys/DEVEL i386
>Description:
The good old definition of the offsetof macro, found in <sys/cdefs.h>, leads
to various compile problems with G++ 3.4 as supplied by FreeBSD. These
problems doesn't exists with "original" version of GCC, it has its own
stddef.h. E.g., GCC's stddef.h use special __offsetof__ extension.
>How-To-Repeat:
Example: the following C++ snippet compiles with original GCC, but doesn't
compile with native FreeBSD GCC.
---------------offsetof.cpp-----
#include <cstddef>
struct A {
int a, b;
};
enum e {
aoff = offsetof(A, a)
};
------------------------------
Compile with
c++ -c offsetof.cpp
fails with
offsetof.cpp:8: error: a casts to a type other than an integral or enumeration type cannot appear in a constant-expression
offsetof.cpp:8: error: '->' cannot appear in a constant-expression
offsetof.cpp:8: error: &' cannot appear in a constant-expression
offsetof.cpp:9: error: enumerator value for `aoff' not integer constant
>Fix:
The definition of offsetof is basically taken from GCC's stddef.h
--- src/sys/sys/cdefs.h Fri Aug 27 17:14:59 2004
+++ src/sys/sys/cdefs.h Mon Jan 10 22:19:30 2005
@@ -240,7 +240,14 @@
* We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
* require it.
*/
+#if defined(__cplusplus) && __GNUC_PREREQ__(3,4)
+#define __offsetof(type, field) \
+ (__offsetof__ (reinterpret_cast <size_t> \
+ (&reinterpret_cast <char &> \
+ (static_cast<type *> (0)->field))))
+#else
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
+#endif
#define __rangeof(type, start, end) \
(__offsetof(type, end) - __offsetof(type, start))
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list