[C++-sig] Calling a C++ function with arguments by reference (lvalues)
Nat Goodspeed
nat at lindenlab.com
Mon Aug 2 17:24:22 CEST 2010
Oded Padon wrote:
> The C++ code is:
>
> void add(int const a, int const b, int const& c)
> {
> c = a + b;
> }
This doesn't even compile under g++ 4.0.1 (Mac):
error: assignment of read-only reference 'c'
I hope you're not using a compiler that accepts such code as legal?
> I must emphasize that I wish to have functions that get arguments
> by reference and change them. Returning the values using the return
> mechanism isn't what I want to do (I have functions that get and set
> many many arguments, and I hardly wish to rewrite them).
<boring anecdote>
Many moons ago I had the dubious pleasure of using a FORTRAN compiler
that was old and dumb even for the time. With this compiler, all
parameters were passed by non-const reference. One of my team was
delegated to write a subroutine that accepted certain parameters. There
was miscommunication about the expected parameter order, and the calling
code ended up passing the integer literal '5' in the parameter slot to
which the subroutine stored its result.
From that point on, everywhere the literal '5' appeared in the source,
the executable was instead referencing the result of some computation.
Merriment ensued as the program confounded all attempts to predict its
behavior.
You are proposing to do the same to the Python interpreter. It's
appropriate for Boost.Python to try to make that difficult.
</boring anecdote>
Suppose you were writing this code from scratch in pure Python. How
would you approach the problem? This won't work:
def add(a, b, c):
c = a + b
def caller():
c = 0
add(1, 2, c)
assert c == 3 # FAIL
One way would be to keep some set of working variables in an object, and
pass that object into the function that wants to modify them:
class Vars(object):
def __init__(self):
self.a = 0
self.b = 0
self.c = 0
def add(a, b, vars):
vars.c = a + b
def caller():
v = Vars()
add(1, 2, v)
assert v.c == 3
Or you could keep working values in a dict, if you prefer dict lookup to
attribute references.
You can code your C++ add() function to accept its 'vars' parameter as a
boost::python::object. If you pass a class object, you can reference
vars.attr("c"). If you pass a dict, you can reference vars["c"].
See also:
http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/embedding.html#python.using_the_interpreter
More information about the Cplusplus-sig
mailing list