Scope guards

J

Jeremy J

Hello,

I recall reading an interesting article on automatic scope guard by A.
Alexandrescu on CUJ.com some time ago. I have since integrated my code
into my project and I find it to be very useful. However I have some
misgivings recently, because the code seems to have been all but
ignored. It took advantage of a C++ 'feature' which guarantees that
the object which a const reference point to will remain while the
const reference exists. This seems somewhat risky to me as I don't
think that the method for maintining such objects is prescribed, and
thus different compilers might have different ways of fullfilling this
guarantee. Basically, is the code 'safe'? I have moved my scope guard
implementation to use boost::function and boost::bind, but this
requires dynamic memory, while Alexandrescu's original implementation
did not.

It seems to me that such an ingenious method would have more exposure
if it was truly safe and efficient. Am I being paranoid? (said the
programmer who inserted scope guards every 20 lines of code ... hehe).

Jeremy Jurksztowicz
 
A

Alf P. Steinbach

* Jeremy J:
Hello,

I recall reading an interesting article on automatic scope guard by A.
Alexandrescu on CUJ.com some time ago. I have since integrated my code
into my project and I find it to be very useful. However I have some
misgivings recently, because the code seems to have been all but
ignored. It took advantage of a C++ 'feature' which guarantees that
the object which a const reference point to will remain while the
const reference exists. This seems somewhat risky to me as I don't
think that the method for maintining such objects is prescribed, and
thus different compilers might have different ways of fullfilling this
guarantee. Basically, is the code 'safe'? I have moved my scope guard
implementation to use boost::function and boost::bind, but this
requires dynamic memory, while Alexandrescu's original implementation
did not.

ScopeGuard was not Andrei's child.

It was Petri Marginean's.

Andrei built some extra machinery on top of that, and they co-authored
the CUJ article.

It seems to me that such an ingenious method would have more exposure
if it was truly safe and efficient. Am I being paranoid? (said the
programmer who inserted scope guards every 20 lines of code ... hehe).

I was under the impression that it's well-known, but perhaps it isn't.

There are only two main issues I know of.

One is that relies on __LINE__, which Visual C++ implements incorrectly
(for Visual C++ use the Microsoft-specific __COUNTER__ macro, urgh).

The second is that the scopeguard destructor catches all exceptions.

Andrei and Petri tried to think of alternatives to that last one, but
couldn't come up with anything better, so.
 
J

Jonathan Turkanis

Alf said:
* Jeremy J:

ScopeGuard was not Andrei's child.

It was Petri Marginean's.

Andrei built some extra machinery on top of that, and they co-authored
the CUJ article.



I was under the impression that it's well-known, but perhaps it isn't.

I think it's quite well known. It's used as an implementation detail in several
Boost libraries; there have been many requests to make it an official part of
Boost, but nobody has taken the trouble to document it, write tests and propose
it for fast track review.
There are only two main issues I know of.

One is that relies on __LINE__, which Visual C++ implements
incorrectly (for Visual C++ use the Microsoft-specific __COUNTER__
macro, urgh).

Right. The problem manifests itself when /ZI (Debug database for edit and
continue) is used. You may find it horrible to use __COUNTER__, but to me it
seems perfectly acceptable, especially since the user never sees it. Since VC6
didn't support __COUNTER__, this problem means the ON_BLOCK_EXIT-type macros are
pretty useless for VC6.
The second is that the scopeguard destructor catches all exceptions.
Andrei and Petri tried to think of alternatives to that last one, but
couldn't come up with anything better, so.

I like the idea of two macros

--- XXX_SCOPE_GUARD, which lets exceptions escape, and
--- XXX_SAFE_GUARD (or XXX_SCOPE_GUARD_NOTHROW) which catches all exceptions.

(Here XXX is code for BOOST)

There are also problems with certain versions of the Metrowerks compiler and
Borland. With Merowerks, to make sure the temporaries are not destroyed
prematurely, you should use

#pragma parse_func_templ off
#pragma parse_munc_templ off

before the use of scope_guard, and reset these compiler options with

#pragma parse_func_templ reset
#pragma parse_munc_templ reset

afterwards. I have verified this with Codewarrior 8.3; I'm not sure it affects
9.x.

With Borland 5.6.4, I've found that occasionally scope_guard just doesn't work,
and I have to write a Borland-specific workaround.

Because of all these complications, I don't use scope_guard much. But it's very
cool.

Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,661
Latest member
FloridaHan

Latest Threads

Top