Cython Equivalent of offsetof doesn't work for some struct members

54 views
Skip to first unread message

Jacob Kovac

unread,
Apr 15, 2015, 2:16:24 AM4/15/15
to cython...@googlegroups.com
I am getting a segmentation fault when attempting to find the offset of a non-array member of a struct, the code I am using:

from cython cimport Py_ssize_t
cdef
extern from "Python.h":
    ctypedef
int Py_intptr_t


ctypedef
struct test:
   
float[2] val_1
   
float val_2

cdef test
* tmp = <test*>NULL

offset_1
= <Py_ssize_t> (<Py_intptr_t>(tmp.val_1) - <Py_intptr_t>(tmp))
offset_2
= <Py_ssize_t> (<Py_intptr_t>(tmp.val_2) - <Py_intptr_t>(tmp))

whereas treating val_2 as an array of length 1 returns the expected results:

from cython cimport Py_ssize_t
cdef
extern from "Python.h":
    ctypedef
int Py_intptr_t


ctypedef
struct test:
   
float[2] val_1
   
float[1] val_2

cdef test
* tmp = <test*>NULL

offset_1
= <Py_ssize_t> (<Py_intptr_t>(tmp.val_1) - <Py_intptr_t>(tmp))
offset_2
= <Py_ssize_t> (<Py_intptr_t>(tmp.val_2) - <Py_intptr_t>(tmp))

The segmentation fault for the first code occurs in both cython version 0.22 and 0.21.2

Stefan Behnel

unread,
Apr 15, 2015, 2:26:25 AM4/15/15
to cython...@googlegroups.com
Jacob Kovac schrieb am 15.04.2015 um 07:13:
> I am getting a segmentation fault when attempting to find the offset of a
> non-array member of a struct, the code I am using:
>
> from cython cimport Py_ssize_t
> cdef extern from "Python.h":
> ctypedef int Py_intptr_t
>
>
> ctypedef struct test:
> float[2] val_1
> float val_2
>
> cdef test* tmp = <test*>NULL
>
> offset_1 = <Py_ssize_t> (<Py_intptr_t>(tmp.val_1) - <Py_intptr_t>(tmp))
> offset_2 = <Py_ssize_t> (<Py_intptr_t>(tmp.val_2) - <Py_intptr_t>(tmp))

You're interested in the memory address here, not the value, so you have to
use (&tmp.val_1).


> whereas treating val_2 as an array of length 1 returns the expected results:
>
> from cython cimport Py_ssize_t
> cdef extern from "Python.h":
> ctypedef int Py_intptr_t
>
>
> ctypedef struct test:
> float[2] val_1
> float[1] val_2
>
> cdef test* tmp = <test*>NULL
>
> offset_1 = <Py_ssize_t> (<Py_intptr_t>(tmp.val_1) - <Py_intptr_t>(tmp))
> offset_2 = <Py_ssize_t> (<Py_intptr_t>(tmp.val_2) - <Py_intptr_t>(tmp))

Arrays are pointers in C, so this works (by accident).

Stefan

Jacob Kovac

unread,
Apr 15, 2015, 1:39:31 PM4/15/15
to cython...@googlegroups.com, stef...@behnel.de
Thank you very much! Not the best at C and I had forgotten the implications of this.
Reply all
Reply to author
Forward
0 new messages