Open C incorrectly implements offsetof
| ID | Unofficial - No ID assigned | Creation date | 2010-11-23 |
| Platform | S60 3rd Edition MR | Devices | none - build environment issue |
| Category | SDK | Subcategory | Open C/C++ |
Overview
Open C defines the offsetof macro incorrectly for some build environments. You have been bitten by this bug if you get errors like this:
file.cpp: At global scope: file.cpp:6: error: expected primary-expression before ',' token file.cpp:6: error: expected `)' before ',' token file.cpp:6: error: `field' was not declared in this scope file.cpp:6: error: expected `,' or `;' before ')' token
on lines that use offsetof.
Description
Open C's <sys/cdefs.h> misuses the __offsetof__ GCC built-in:
#define __offsetof(type, field) \
(__offsetof__ (type,field))
__offsetof__ isn't the same as __builtin_offsetof:
- __offsetof__ has one argument and "is equivalent to the parenthesized expression, except that the expression is considered an integral constant expression even if it contains certain operators that are not normally permitted in an integral constant expression".
- __builtin_offsetof has two arguments and offsetof(type, member) can be simply defined to __builtin_offsetof(type, member)
How to reproduce
Compile the following C++ source code with Open C (SYSTEMINCLUDE \epoc32\include\stdapis) and a toolchain with a GCC version 3.x:
#include <cstddef>
#if !defined(__GNUC__) || __GNUC__ >= 4
#error this test is meant for GCC 3.x
#endif
struct type { int field };
static const int x = offsetof(type, field);
Compilation should fail with:
file.cpp: At global scope: file.cpp:6: error: expected primary-expression before ',' token file.cpp:6: error: expected `)' before ',' token file.cpp:6: error: `field' was not declared in this scope file.cpp:6: error: expected `,' or `;' before ')' token
Solution
Manually change the following lines in <sys/cdefs.h> (\epoc32\include\stdapis\sys\cdefs.h) from:
#define __offsetof(type, field) \
(__offsetof__ (type,field))
to:
#define __offsetof(type, field) __offsetof__(reinterpret_cast <size_t> \
(&reinterpret_cast <const volatile char &> \
(static_cast<type *> (0)->field)))


(no comments yet)