4

On my 64-bit office desktop this compiles fine:

#include <Python.h>
#include <numpy/arrayobject.h>

...

Py_Initialize();
import_array();

// Build array object
long int NUMEL=3;
PyObject *out_array = PyArray_SimpleNew(1, &NUMEL, NPY_DOUBLE);

Conversely, on my 32-bit laptop this fails producing the error:

 error: invalid conversion from ‘long int*’ to ‘npy_intp* {aka int*}’ [-fpermissive]
     PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)

Alternatively if I declare int NUMEL=3 instead, the code will compile on 32-bit machine but not on the 64-bit one. I suspect that npy_intp is platform dependent. As I cannot define NUMEL of npy_intp type (as in practice it is passed by other C/C++-only routines), is there a way to conditionally define NUMEL depending on the platform within the C++-code?

maurizio
  • 745
  • 1
  • 7
  • 25

1 Answers1

2

npy_intp is typedef'ed here to be:

typedef Py_intptr_t npy_intp;

And Py_intptr_t is defined in the Python C source in pyport.h. It is highly system dependent, see that source for details, but for most cases, unless you are dealing with Microsoft's Visual C being C89, you have stdint.h and can simply include it and use intptr_t as your type. In C++ this comes as std::ptrdiff_t, take a look also at its unsigned counterpart, std::size_t.

As a last resort, you could always replicate what Python does with something like:

#if sizeof(void *) <= sizeof(int)
    typedef int my_type;
#elif sizeof(void *) <= sizeof(long)
    typedef long my_type;
#else
    typedef long long my_type;
#endif

which will work on almost all platforms, although you may find it to not be portable to same weird corner case system.

Jaime
  • 65,696
  • 17
  • 124
  • 159
  • Thanks. I ignored the existence of `stdint.h` (being mostly a self-learner). So if I got it correctly, `NUMEL` can be given of any `intN_t` type. But any function that passes `NUMEL` to `PyArray_SimpleNew` must pass it as `intptr_t`. Nevertheless this is not a problem, insofar as casting from `intN_t` to `intptr_t` is automatically performed. – maurizio Jun 08 '16 at 13:49