Search code examples
cythonpass-by-referencepass-by-value

cython pass by value situation


I have met an interesting case regarding cython pass by value. The code is written in jupyter notebook:

%%cython -a
#cython: language_level = 3
#distutils: language = c++
from libcpp.map cimport map
from libcpp.string cimport string
cdef fun( map[ string, double ] a ):
    a[ b'H' ] = 10

cdef map[ string, double ] a
a[ b'H' ] = 0
fun( a )
print( a[ b'H' ] )

The return value is still 0

If we write it in python:

def fun( a ):
   a[ 'a' ] = 10
a = { 'a' : 5 }
fun( a )
print( a[ 'a' ] )

The answer will be 10

Can some experts explain why cython and python show different behavior?


Solution

  • If you want to pass by reference in C++ or a C++-objects in Cython you should pass it by reference, i.e. the signature of the function fun should be

    cdef fun( map[ string, double ] &a ):
         ...
    

    All Python-objects are pointers of type PyObject * and signature

    def fun(object a):
       ...
    

    is approximately translated to

    PyObject *fun(PyObject *a){
          ...
    }
    

    i.e. arguments are passed as pointers, which corresponds to C++'s-references in pure C.