Issues with __buildtin_offsetof() and workarounds

Lars Kurth larsk@symbian.org
Thu Mar 25 20:46:00 GMT 2010


Dear GCC folks,

we are in the process of porting the Symbian codebase to GCC 4.4.1 and 
we have a number of issues with __builtin_offsetof().

I was wondering whether there is any good porting advice around: others 
must have had similar issues in the past. What I am looking for is a 
mixture of advice and our assumptions being verified. The aim is to 
facilitate a smooth transition to GCC.

1) Cannot pass objects of non-POD type to __builtin_offsetof()
Related to http://gcc.gnu.org/ml/gcc/2003-04/msg00970.html - the key 
issue with __builtin_offsetof() seems to be that for virtual base 
classes it is not possible to calculate the offset.

Now we only use simple inheritance and also do not use virtual bases, so 
we should be safe. Is this a true assumption? I came across 
http://www2.research.att.com/~bs/C++0xFAQ.html#PODs, which would at 
least vindicate that view partly.

Thus we were thinking of using "-Wno-invalid-offsetof" for now to 
supress these warnings.

2) Arrays in __builtin_offsetof()  are not const address expressions (as 
the C/C++ standard requires)
In most cases I can work around this by using the following pattern:

    offsetoff(myclass, member) + arrayindex*typeof(member)

Unfortunately this is pretty ugly and the meaning of the code is 
obfuscated. Is there a more readable convention in C++ which compiles?

3) Other non const address expressions in __builtin_offsetof() (as the 
C/C++ standard requires)
We have quite a few instances of low-level code in the OS where 
offsetof() is used to make assertions about how objects are layed out. 
This mainly happens where C++ code interfaces with assembler code. Many 
of these assertions have a non-const expression in the member argument 
of offsetof. It would be a shame to get rid of this safety net.

The proprietary compiler that we use still defines offsetof as

    #define _FOFF(c,f) (((TInt)&(((c *)0x1000)->f))-0x1000)

and works. GCC falls over in many instances, thus we switched to 
__builtin_offsetof(). However the old definition still appears to works 
in the cases mentioned if we locally overwrite the definition of 
offsetof(). Is there any convention in C++ to handle these?

I was thinking along the lines of introducing for these cases

    #define _FOFF_UNSAFE(c,f) (((TInt)&(((c *)0x1000)->f))-0x1000) // 
... OR

    #define unsafe_offsetof(c,f) (((TInt)&(((c *)0x1000)->f))-0x1000)

That way we would make clear that this macro is used at the users own 
risk and we will be able to spot and replace such instances easily in 
future.

Any help, experiences others that have ported a large codebase to GCC 
would be appreciated

Best Regards
Lars
Symbian Foundation Limited is a Company Limited by Guarantee and not having a Share Capital registered in England and Wales under its number 6683783 whose registered address is 1 Boundary Row, Southwark, London SE1 8HP.



More information about the Gcc-help mailing list