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