{"id":1865,"date":"2012-11-19T18:38:01","date_gmt":"2012-11-20T01:38:01","guid":{"rendered":"http:\/\/the-witness.net\/news\/?p=1865"},"modified":"2015-03-26T14:49:17","modified_gmt":"2015-03-26T21:49:17","slug":"scopeexit-in-c11","status":"publish","type":"post","link":"http:\/\/the-witness.net\/news\/2012\/11\/scopeexit-in-c11\/","title":{"rendered":"scope(exit) in C++11"},"content":{"rendered":"<p>I really like the <a href=\"http:\/\/dlang.org\/statement.html#ScopeGuardStatement\" onclick=\"_gaq.push(['_trackEvent', 'outbound-article', 'http:\/\/dlang.org\/statement.html#ScopeGuardStatement', 'scope(exit) statements in D']);\" >scope(exit) statements in D<\/a>. 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++.<\/p>\n<p>Turns out this can be implemented easily using some of the new C++ features. I'm not a big fan of C++11; for the most part I think it adds even more complexity to an already complex language. However, I have to admit that some of the features can be useful, when used with care and moderation.<\/p>\n<p>I think this is one of such cases. If you can get past the weird syntax, lambdas can be very powerful. What I find most useful is to be able to define local functions (closures) that can access the local variables of the enclosing scope.<\/p>\n<p>In our case, what we want to do is to define some code that is executed at the end of the scope to cleanup objects allocated in the current scope. This is easily achieved allocating an object on the stack that invokes a lambda function that wraps our custom cleanup code:<\/p>\n<pre>#include &lt;functional&gt;\r\n\r\nstruct ScopeExit {\r\n    ScopeExit(std::function f) : f(f) {}\r\n    ~ScopeExit() { f(); }\r\n    std::function f;\r\n};\r\n\r\n#define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2)\r\n#define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2\r\n#define SCOPE_EXIT(code) \\\r\n    ScopeExit STRING_JOIN2(scope_exit_, __LINE__)([=](){code;})\r\n<\/pre>\n<p>Then you can write code like:<\/p>\n<pre>int * ip = new int[16];\r\nSCOPE_EXIT(delete [] ip);\r\n\r\nFILE * fp = fopen(\"test.out\", \"wb\");\r\nSCOPE_EXIT(fclose(fp));\r\n<\/pre>\n<p>I know you can go to greater lengths to mimic the D syntax, and that Boost also provides similar functionality, but this does all we need in less than 10 lines of code.<\/p>\n<p>Sadly we cannot really use this on The Witness, because I'm not sure we are yet ready to drop support for platforms and compilers that do not implement the required C++11 functionality.<\/p>\n<p><em><strong>Update:<\/strong><\/em><\/p>\n<p>As mentioned by Daniel in the comments, you don't really want to use std::function in this case. A quick look at the assembly output confirms that the generated code is horrible. It makes a lot more sense to wrap the closure explicitly and rely on type inference to allocate the wrapper object on the stack:<\/p>\n<pre>template &lt;typename F&gt;\r\nstruct ScopeExit {\r\n    ScopeExit(F f) : f(f) {}\r\n    ~ScopeExit() { f(); }\r\n    F f;\r\n};\r\n\r\ntemplate &lt;typename F&gt;\r\nScopeExit&lt;F&gt; MakeScopeExit(F f) {\r\n    return ScopeExit&lt;F&gt;(f);\r\n};\r\n\r\n#define SCOPE_EXIT(code) \\\r\n    auto STRING_JOIN2(scope_exit_, __LINE__) = MakeScopeExit([=](){code;})\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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. \u2026<\/p>\n<p class=\"continue-reading-button\"> <a class=\"continue-reading-link\" href=\"http:\/\/the-witness.net\/news\/2012\/11\/scopeexit-in-c11\/\">Continue reading<i class=\"crycon-right-dir\"><\/i><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[],"_links":{"self":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/1865"}],"collection":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/comments?post=1865"}],"version-history":[{"count":14,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/1865\/revisions"}],"predecessor-version":[{"id":2956,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/1865\/revisions\/2956"}],"wp:attachment":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/media?parent=1865"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/categories?post=1865"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/tags?post=1865"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}