octave-maintainers
[Top][All Lists]
Advanced

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

FYI: unwind_protect improved


From: John W. Eaton
Subject: FYI: unwind_protect improved
Date: Tue, 23 Jun 2009 09:26:43 -0400

On 23-Jun-2009, Jaroslav Hajek wrote:

| There's a generic unwind_protect::protect_var method able to handle a
| variable of any assignable & copyable class.
| unwind_protect::protect_mem is also provided though it will probably
| be very seldom used (given that you can protect a NDArray or whatever
| with protect_var).
| 
| using string tags for unwind_protect frames is now deprecated:
| 
|   unwind_protect::begin_frame ("tree_evaluator::visit_simple_for_command");
| ...
|   unwind_protect::run_frame ("tree_evaluator::visit_simple_for_command");
| 
| In particular, if you misspelled the string in run_frame, it would
| silently run all frames down the stack (!).
| 
| The proper usage is now:
| 
|   unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame ();
| ...
|   unwind_protect::run_frame (uwp_frame);
| 
| which allocates the frame info as a local variable (in fact, it's
| simply the stacksize at the moment of query). This is also somewhat
| more efficient, as there's no string manipulation when processing the
| stack, neither is there need to store them in the stack.
| 
| The old tags mechanism is still supported, but the methods are marked
| as deprecated. They should be removed at some point.
| 
| It is also possible to protect a single variable locally, if
| performance is of particular concern:
| 
| {
|    unwind_protect::restore_var<bool> flag_protect (flag); // will
| auto-restore flag at end of block
|    flag = temporary value;
|    ...
| }
| 
| this is more efficient because the compiler can inline everything.

Thanks.  This is a big improvement.  The old design was copied from
bash early in Octave's history.  Since bash is written in C, it
can't take advantage of these kinds of constructor/destructor
features, and I wasn't smart enough to see a better way.  Oh, and
templates weren't part of C++ yet...

I think the names "saved_var" and "saved_mem" might be better than
"restore_var" and "restore_mem".  It usually seems better to me to
name objects as things rather than actions.

You have

    private:

    // No copying!
    void operator = (const restore_mem&); 

in the restore_mem class (and a similar declaration in the restore_var
class) but I don't think this actually prevents copying.  For example,
try this program:

  class foo
  {
  public:
    foo (void) { }
    ~foo (void) { }
  private:
    void operator = (const foo&);
  };

  int
  main (void)
  {
    foo x;
    foo y (x);
    foo z = y;
    return 0;
  }

I think that using

    private:
      restore_mem (const restore_mem&);

is sufficient, but I usually write

    private:
      // No copying!
      X (const X&);
      X& operator = (const X&);

to prevent copying in a class X.

jwe


reply via email to

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