[Pyrex] size_t and reference passing in 64-bit platforms

Francesc Alted falted at openlc.org
Fri Jan 9 14:32:13 CET 2004


Hi,

I'm having problems when using the special type "size_t" and perhaps you can
give me a hand. What I want is to pass a size_t data type per reference to a
C function like in:

--
#include "test_c.h"

size_t read_c(size_t *id) {
  return *id*2;
}
--

where "test_c-h" reads:

--
#include <stdlib.h>

size_t read_c(size_t *id);
--

As size_t is not exactly a primitive type, I mapped it to a "int" type, like
in:

cdef extern from "stdlib.h":
  ctypedef int size_t

Then, I've declared the wrapper to the C function:

cdef extern from "test_c.h":
   size_t read_c(size_t *id)

and finally, the python function

def readC(size_t id):
    cdef size_t id2
    id2 = id
    return read_c(&id2)

The testbed python code is simple:

import test  # The pyrex extension
print "readC(10)-->", test.readC(10)


Well, this works very well, without any compiler warnings, but only in
32-bit platforms. If I try to compile the above code on a 64-bit machine
(I've tried an AMD Opteron with SuSE Linux), the following warning appears:

falted at amd64-linux1:~> gcc -fPIC -I ~/bin-opteron/include/python2.3 -c test.c
test.c: In function `__pyx_f_4test_readC':
test.c:53: warning: passing arg 1 of `read_c' from incompatible pointer type

and the binaries works bad:

falted at amd64-linux1:~> python test2.py
readC(10)--> 85899345940  # I would have expected 20 (!)

However, if I change the size_t declaration in test.pyx to read:

cdef extern from "stdlib.h":
  ctypedef long size_t

then, it compiles without a warning:

falted at amd64-linux1:~> pyrexc test.pyx
falted at amd64-linux1:~> gcc -fPIC -I ~/bin-opteron/include/python2.3 -c test.c
falted at amd64-linux1:~>

and the binary works just fine:

falted at amd64-linux1:~> python test2.py
readC(10)--> 20


On the another hand, defining size_t as long gives warnings on 32-bit
platforms:

falted at intel32-linux1:~> gcc -fPIC -I /usr/include/python2.3 -c test.c
test.c: In function `__pyx_f_4test_readC':
test.c:50: warning: passing arg 1 of `read_c' from incompatible pointer type

it does, however, generate good code:

falted at intel32-linux1:~> python test2.py
readC(10)--> 20

I guess "size_t" takes 64 bits on a 64-bit platform, but 32 bits on a 32-bit
one. Also, I've noted too that a "long" type takes 64 bits in a 64-bit
platform and 32 bits on a 32-bit one. So, I would say that mapping size_t to
long is the right way to go with pyrex and, in fact, this always leads to
correct binaries (as far as I can say) in both 32 and 64-bit platforms.
However, I can't get rid of the warnings on 32-bit platforms, as I would
like to.

Any hint?. Thanks

-- 
Francesc Alted






More information about the Pyrex mailing list