8 ms·
Scope exit in C++11 (2012)
- deleted 9y ago[deleted]
- jwilk 9y agoThe site doesn't load for me. Here's an archived copy: https://archive.is/srQvw https://archive.is/srQvw
- jordigh 9y agoIt's nice to see some D ideas make it into C++. I think that D is kind of like Mercurial: both less popular than some other wildly popular alternative, but we still hope that at least some of their ideas trickle back into the more popular sibling.
- joejev 9y agoThis pattern was possible with a scoped class in c++ 98.
- katastic 9y agoI absolutely agree. C++ is at least a decade behind D. Literally. The kinds of features that eventually hit C++, D actually had for at least ten years. I think of D as a clean break. A major version upgrade with an API break. Whereas C++ has committees that move incredibly slowly, D has two architects who are decades long professionals and considered experts in their fields. It has focus, and it's not concerned with making code from the 70's compile on a modern compiler. I simply cannot enumerate all of the features I use from D that I use every day that have become second-nature. Until I try to code in C++ again and I'm like, "The !@$@!ing order of declarations matter?! I can't make circular references without manually writing forward declarations?!" It feels like banging rocks together to make a 747.
- w8rbt 9y agoI think that's mainly because C++ is an ISO standard used all over the world by big business and governments. So its standards are released less often and with a great deal of testing and care. I bet you will be able to specify -std=c++Whatever for the next 50 to 100 years, maybe longer.
- klipt 9y agoC++ is like English - widely used, and steals like hell from other languages. D is probably more like, hmm, Esperanto? Carefully designed but few people know about it. Haskell would probably be Lojban...
- smitherfield 9y agoWhile I'm a C++ fan, I'd readily concede it's much closer kin to (verbose) German than (laconic) English. Java's even more verbose, so it probably has the stronger claim on German,* which I guess makes C++ Danish and Perl English. :) * https://en.wikipedia.org/wiki/Andy_Bechtolsheim https://en.wikipedia.org/wiki/Andy_Bechtolsheim
- maxlybbert 9y agoI’m pretty sure D got the idea from C++: http://www.drdobbs.com/article/print?articleId=184403758&siteSectionName=cpp http://www.drdobbs.com/article/print?articleId=184403758&sit... (note that there are three pages).
- favorited 9y agoThis is pretty similar to std::lock_guard (and similar RAII types). Except instead of unlocking (or tearing down a resource, etc.) upon destruction, it invokes a lambda.
- lyricaljoke 9y agoThis type of construct is unnecessary in C++11; the presence of RAII containers and structures totally obviates it. C++ provides a language-level construct for logic performed at the end of object lifetime (i.e., when value types fall out of scope or when heap-allocated objects are deleted): the destructor! This person is describing an error-prone reimplementation of std::unique_ptr with a custom deleter. I could understand the value of an article like this if the use of C++11 were not allowed, but given that the article is written with C++11 in mind, I fear the author has totally missed the point of RAII-style resource management that the newer language-level constructs provide. Deterministic destruction and associated logic, as well as the RAII strategies that follow, are perhaps the greatest strength of C++. Languages like Rust have gone on to improve this even further by eliminating some of the greatest sources of error. Capabilities like this don't seem accurately described as C++ learning from D; indeed, if D provides hooks for running logic when names fall out of scope, that seems more accurately described as vice versa.
- emsy 9y agoThat's if you program "object oriented". In my experience object orientation in C++ often means something entirely different than in a GCed language like Java or C#. It's totally reasonable to program data-oriented in C++, especially for time critical applications like games. Unfortunately, this rules out many abstractions and mechanisms that make sense in a modern C++ application.
- katastic 9y agoCould you give some concrete examples of your point? RAII works fine in games.
- mehrdadn 9y agoWhat everybody seems to miss (including in the other comments here) is the fact that no kind of hackery with destructors will ever make them equivalent to scope(exit) or finally{}, because of the simple reason that destructors invoked via exceptions can't throw their own exceptions. And this makes sense, because destructors are meant to release resources, whereas finally/scope(exit) are meant to execute after prior operations in a LIFO manner. Not all operations that need to occur in a LIFO manner are inherently tied to resource acquisition. More fundamentally, one is inherently about data, and the other is inherently about control-flow... simply put, they're different tools with different use cases, even though people don't bother to make the distinction. Nevertheless, if people insist on using the same hammer for both nails, the language needs to address this fundamental issue before people can claim it's possible to do scope(exit) or the equivalent in C++.
- lomnakkus 9y agoI'm not sure I understand what you mean. For your "release resources" point: fclose() can fail, yet in fstream::~fstream() that must be ignored. So that's not great. For your "execute after prior operations in LIFO manner" point... what is the purpose except to clean up resources? If it isn't about scoped resources, then what is it about, given that defer(...) is explicitly about scope? I mean, if "defer" wasn't about that, we'd just write a few more statements doing the thing and not bother with the whole defer(...) thing?!?
- mehrdadn 9y ago> For your "release resources" point: fclose() can fail, yet in fstream::~fstream() that must be ignored. So that's not great. No, fclose() cannot fail to close the file. The return code merely tells you whether any pending write operations have failed in the meantime, which is unrelated to the releasing of the FILE. The FILE will be closed either way. The C standard is explicit about this: Whether or not the call succeeds, the stream is disassociated from the file and any buffer set by the setbuf or setvbuf function is disassociated from the stream (and deallocated if it was automatically allocated). http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#page=282 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#pa... > For your "execute after prior operations in LIFO manner" point... what is the purpose except to clean up resources? Well, fflush() is an easy example. Or, any logging that must occur at the end of a function call regardless of its success or failure. Or, really, anything else that isn't releasing a resource...
- smitherfield 9y agoYou can do the same thing with no C++11 features other than C99 variadic macros. (IMO cleaner, too). #define SCOPE_EXIT(...)\ struct SE##__LINE__##_{~SE##__LINE__##_(){__VA_ARGS__;}}se##__LINE__##_
- saagarjha 9y agoI'm curious: is __VA_ARGS__ part of the standard, or just widely used?
- tzahola 9y agoYeah but that’s kinda cheating
- mehrdadn 9y agoNo, you can't generally put anything useful in there. The whole point of a lambda is the [&]. If you can't capture local variables then it's practically useless.
- maxlybbert 9y agoAlexandrescu managed to do it in 2000: http://www.drdobbs.com/article/print?articleId=184403758&siteSectionName=cpp http://www.drdobbs.com/article/print?articleId=184403758&sit... (note that there are three pages). The version in Facebook Folly was cleaned up because of C++11, but this wasn’t a new technique five years ago.
- EgoIncarnate 9y ago(2012)
- laythea 9y agoWow, so much debate over the specific manner in which to solve a problem. More needed on the which problems to solve, I think.