[Cython] Add support for the offsetof() C macro

Sturla Molden sturla at molden.no
Fri Apr 5 19:31:44 CEST 2013


On 03.04.2013 12:53, Nikita Nemkin wrote:

>> offsetof() is not supported by current Cython, and I have not found any
>> workaround (except hardcoding offsets for a specific architecture and
>> compiler, but this is obviously wrong).
>
> offsetof() would certainly be very useful, but in the meantime
> offsetof(Struct, field) can be replaced with:
>
>      <Py_ssize_t>&(<Struct*>NULL).field
>
> It's not ANSI C, but is portable enough.

This will dereference a NULL pointer.

Also, Py_ssize_t is not guaranteed to be long enough to store a pointer 
(but Py_intptr_t is). Use Py_intptr_t when you cast pointers to integers.


> Another option (for extern or public structs only) is to abuse
> renaming:
>
>      enum:
>          Struct_offsetof_field1 "offsetof(Struct, field1)"

This will fail if "Struct" is name mangled by Cython. Basically it 
requires that it is defined outside of the Cython code, e.g. in a header 
file.



To be valid C, offsets must be computed:

cdef Struct tmp
cdef Py_ssize_t offset
offset = <Py_ssize_t> (<Py_intptr_t>&(tmp.field) - <Py_intptr_t>&(tmp))

For that reason, most C compilers defines offsetof as a builtin function.



Sturla


More information about the cython-devel mailing list