scope(exit) in C++11

A C++ note in passing from an indie game developer. He notes that Boost has a similar feature already (see the BOOST_SCOPE_EXIT macros and discussion of alternatives) but likes that you can write the basic feature yourself in under 10 lines, have it work like a statement instead of a BEGIN/END macro pair, and use it with other C++11 features like lambdas.

scope(exit) in C++11

I really like the scope(exit) statements in D. They allow you to keep the cleanup code next to the initialization code making it much easier to maintain and understand. I wish we had them in C++.

Turns out this can be implemented easily using some of the new C++ features...

Continue reading...

Add a Comment

Comments are closed.

Comments (7)

0 0

Zhihao Yuan said on Nov 20, 2012 03:41 PM:

This library is not ideal enough. I have a better solution, which supports the anonymous guard and the named guard at the same time, plus the commit/rollback semantics:

http://4bsd.biz/post/35333867680/a-simplified-transctional-scopeguard

Maybe you should consider to follow my blog, which is

4BSD -- http://4bsd.biz/

I post cutting edge discoveries wink
0 0

adrian.hodos said on Nov 21, 2012 11:40 AM:

I don't see why this is better than using std::unique_ptr with a custom deleter. Also it has the downside that it actually separates the moment of binding between the resource and its destructor.
Consider this example :

FILE *fp = fopen(argv[1], "r");
if (fp == nullptr)
return false;
defer(fclose(fp));

It's all too easy for someone to insert some lines of code above the defer(...) macro and have the function return early, never noticing that fp will leak.

FILE *fp = fopen(argv[1], "r");
if (fp == nullptr)
return false;
if (somethings_not_right_with(fp))
return false; // oops, fp leaks
defer(fclose(fp));

The unique_ptr approach does not have this problem.
struct FILE_deleter {
void operator()(FILE* fp) const {
if (fp)
fclose(fp);
}
};

std::unique_ptr<FILE, FILE_deleter> fp_handle(fopen(...));

Plus, as a bonus, it does not require ugly macros and works with non C++11 code smile
0 0

adrian.hodos said on Nov 21, 2012 11:41 AM:

Christ allmighty, the formatting :((
0 0

Zhihao Yuan said on Nov 21, 2012 12:01 PM:

It's not, as I pointed out in my blog. defer() is good for implementing transactional semantics; scope guarding is just one use.

BTW, unique_ptr does not support non-pointer resources, like a file descriptor.
0 0

adrian.hodos said on Nov 21, 2012 12:09 PM:

Yes, unique_ptr is limited to pointers, but its not terribly hard to code a unique_handle that deals with non pointer resources, or find a library out there that offers it out of the box.
0 0

Blog Staff said on Nov 21, 2012 06:03 PM:

Note: You can put code in "pre" & "/pre" blocks.


#include <iostream>
int main() { std::cout << "Hello!" }
0 0

zahir said on Nov 22, 2012 09:51 AM:

RAII please. I guess such macros do declare an in-scope class and a variable out of the definition, but that article for scope(exit) is just praying on the RAII principle.