
Scope exit in C++11 (2012) - noch
http://the-witness.net/news/2012/11/scopeexit-in-c11/
======
mehrdadn
What 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++.

~~~
deathanatos
> _destructors invoked via exceptions can 't throw their own exceptions_

`finally`, in languages that have it (and presumably, scope(exit) too), face
fundamentally the same problem with exceptions that destructors do: if an
exception is already propagating, and you throw another one, _what happens?_ ,
since you (presumably) can't have two exceptions. C++ says tough / don't do
that / you're terminated. Other languages just forget about the other
exception, and you lose the context (which can be a pain to debug; though I
think more recent versions of Python, for example, will attach the original
exception as a "context" to the new one) but your program continues execution.

Languages that expose a result object, e.g., Result in Rust, force you to deal
with the issue yourself, essentially, by deciding at the site what to do with
it. (The downside being the increased amount of code, though to some extent I
believe the language can supply tooling to help there; Rust is again a good
example. The upside is you get to choose what happens.)

(I see these more as a tradeoff, that different languages have different
opinions about.)

~~~
cjalmeida
Java from the beginning allows you to chain exceptions and that is a core part
of debugging.

In Python this is a very recent construct and few libraries use it,
unfortunately.

------
lyricaljoke
This 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
That'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.

------
jordigh
It'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.

~~~
klipt
C++ 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
While 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)

------
favorited
This 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.

------
jwilk
The site doesn't load for me. Here's an archived copy:

[https://archive.is/srQvw](https://archive.is/srQvw)

------
laythea
Wow, so much debate over the specific manner in which to solve a problem. More
needed on the which problems to solve, I think.

------
EgoIncarnate
(2012)

------
smitherfield
You 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
I'm curious: is __VA_ARGS__ part of the standard, or just widely used?

~~~
jwilk
It's part of the standards since C99 and C++11.

