Skip to content Skip to sidebar Skip to footer

Pointer-type Mismatch With Pyarray_simplenew

I am creating a module for Python with Numpy using the C API and encounter weird incompatibilities with the output of PyArray_SimpleNew, which I would like to understand. But first

Solution 1:

To answer your question about why you're receiving a warning about "ISO C forbids conversion of object pointer to function pointer type", I examined the source code for numpy.

PyArray_SimpleNew is a macro defined in numpy/ndarrayobject.h on line 125:

#define PyArray_SimpleNew(nd, dims, typenum) \
        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)

Which will expand line A as:

PyObject * A = PyArray_New(&PyArray_Type, 1, dims, typenum, NULL, NULL, 0, 0, NULL); // Line A

PyArray_New is itself a macro defined in numpy/__multiarray_api.h on line 1017:

#define PyArray_New \
        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
         PyArray_API[93])

Which will expand line A as:

PyObject * A = (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *))
                PyArray_API[93])(&PyArray_Type, 1, dims, typenum, NULL, NULL, 0, 0, NULL); // Line A

This complex expression can be simplified to:

// PyObject * function93(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)typedef PyObject * (*function93)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);

// Get the PyArray API function #93, cast the function pointer to its// signature, and call it with the arguments to `PyArray_New`.
PyObject * A = (*(function93) PyArray_API[93])(&PyArray_Type, 1, dims, typenum, NULL, NULL, 0, 0, NULL); // Line A

The part causing the forbidden conversion is:

*(function93) PyArray_API[93]

In numpy/__multiarray_api.h on lines 807, 810, and 812 PyArray_API is declared as void **. So PyArray_API[93] is a void * (i.e., an object pointer) which is being cast as a function pointer.

I'm not really familiar with NumPy or its C-api, but it looks like you are using it properly. NumPy just happens to be using some non-standard, undefined behavior internally that GCC supports but the ISO standard does not (i.e., NumPy is not portable by the ISO standard).

See also [SciPy-User] NumPy C API: where does casting pointer-to-object to pointer-to-function come from?

Post a Comment for "Pointer-type Mismatch With Pyarray_simplenew"