help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Realtime cost of call by value


From: John W. Eaton
Subject: Re: Realtime cost of call by value
Date: Wed, 29 Oct 2003 17:54:44 -0600

As things are now, I don't think there is any way to do precisely what
you want, but with a few changes, it could be possible.

Instead of get_global_value and matrix_value, we need functions like

  octave_value&
  get_global_reference (const std::string& nm)
  {
    static octave_value foobar;

    symbol_record *sr = global_sym_tab->lookup (nm);

    if (sr)
      {
        octave_value& sr_def = sr->def ();

        if (sr_def.is_undefined ())
          error ("get_global_reference: undefined symbol `%s'", nm.c_str ());
        else
          {
            sr_def.make_unique ();

            return sr_def;
          }
      }
    else
      error ("get_global_reference: unknown symbol `%s'", nm.c_str ());

    return foobar;
  }

in variables.cc,

  Matrix&
  octave_matrix::matrix_reference (void)
  {
    return matrix.matrix_reference ();
  }

in ov-re-mat.cc, and

  Matrix&
  Matrix::matrix_reference (void)
  {
    matrix.make_unique ();
    return *this;
  }

in dMatrix.cc.  Then you can use these functions as follows:

  DEFUN (somefun, args, , "")
  {
    octave_value& foo = get_global_reference ("foo");

    Matrix& foo_mat = foo.matrix_reference ();

    foo_mat(0,0) = 42;

    return octave_value ();
  }

Using make_unique() in both get_global_reference and matrix_reference
preserves the (apparent) call-by-value semantics if someone happens to
do something like

  global foo = rand (1000);

  bar = foo

  somefun ();

(given the definition of somefun above).  Otherwise, the values of
both foo and bar would change, and I think that would be quite
surprising to most Octave users.

Note that with these *_reference functions, you no longer need to use
the set_global_value function since you are modifying the actual
storage associated with the global name that you've referenced.

Also, because you are working with the actual storage, there is no way
to do any kind of implicit type conversion as you can with the *_value
functions (i.e., ov.complex_matrix_value () will work wether the
actual type of ov is a scalar, complex scalar, matrix, or complex
matrix).  So you need to know exactly what data type you are working
with.

Is it worth adding these functions?  I suppose I would vote yes even
though they are likely to lead to some confusion.  For example, if you
write

  DEFUN (somefun, args, , "")
  {
    octave_value& foo = get_global_reference ("foo");
    Matrix foo_mat = foo.matrix_reference ();

    foo_mat(0,0) = 42;

    return octave_value ();
  }

you will not modify the global variable value (because foo_mat is now
a copy of the object that was returned from get_global_reference
instead of another reference to it).  So a single & makes a big
difference, and it is a hard to spot bug...

jwe



-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web:  http://www.octave.org
How to fund new projects:  http://www.octave.org/funding.html
Subscription information:  http://www.octave.org/archive.html
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]