Live data from Hacker News

C++ says “We have try... finally at home”

devblogs.microsoft.com

71–80 of 152 posts

Re: C++ says “We have try... finally at home”

#71
post #3

I like how Swift solved this: there's a more universal `defer { ... }` block that's executed at the end of a given scope no matter what, and after the `return` statement is evaluated if it's a function scope. As such it has multiple uses, not just for `try ... finally`.

#include #define RemParens_(VA) RemParens__(VA) #define RemParens__(VA) RemParens___ VA #define RemParens___(...) __VA_ARGS__ #define DoConcat_(A,B) DoConcat__(A,B) #define DoConcat__(A,B) A##B #define defer(BODY) struct DoConcat_(Defer,__LINE__) { ~DoConcat_(Defer,__LINE__)() { RemParens_(BODY) } } DoConcat_(_deferrer,__LINE__) int main() { { defer(( std::cout

And here I thought we were trying to finally kill off pre-processor macros.

Re: C++ says “We have try... finally at home”

#72
Calling arbitrary callbacks from a destructor is a bad idea. Sooner or later someone will violate the requirement about exceptions, and your program will be terminated immediately. So I'd only use this pattern in -fno-exceptions projects.

In a similar vein, care must be taken when calling arbitrary callbacks while iterating a data structure - because the callback may well change the data structure being iterated (classic example is a one-shot event handler that unsubscribes when called), which will break naïvely written code.

Re: C++ says “We have try... finally at home”

#73
post #9
post #5

Earlier quoted context omitted.

HN has some heuristics to reduce hyperbole in submissions which occasionally backfire amusingly.

Yeah it's a huge mistake IMO. I see it fucking up titles so frequently, and it flies in the face of the "do not editorialise titles" rule: [...] please use the original title, unless it is misleading or linkbait; don't editorialize. It is much worse, I think, to regularly drastically change the meaning of a title automatically until a moderator happens to notice to change it back, than to allow the occasional somewha…

While I disagree with you that it's "a huge mistake" (I think it works fine in 95% of cases), it strikes me that this sort of semantic textual substitution is a perfect task for an LLM. Why not just ask a cheap LLM to de-sensationalize any post which hits more than 50 points or so?

Re: C++ says “We have try... finally at home”

#74
> In Java, Python, JavaScript, and C# an exception thrown from a finally block overwrites the original exception, and the original exception is lost.

Pet peeve of mine: all these languages got it wrong. (And C++ got it extra-wrong.)

The error you want to log or report to the user is almost certainly the original exception, not the one from the finally block. The error from the finally block is probably a side effect of the original exception. Reporting the finally exception obscures information about the root cause, making it harder to debug the problem.

Many of these languages do attach the original exception to the new exception in some way, so you can get at it if you need to, but whatever actually catches and logs the exception later has to go out of its way to make sure to log the root cause rather than some stupid side effect. The hierarchy should be reversed: the exception thrown by `finally` should be added as an attachment to the original exception, perhaps placed in a list of "secondary" errors. Or you could even just throw it away, honestly the original exception is almost always all you care about anyway.

(C++ of course did much worse by just crashing in this scenario. I imagine this to be the outcome of some debate in the committee where they couldn't decide which exception should take priority. And now everyone has internalized this terrible decision by saying "well, destructors shouldn't throw" without seeming to understand that this is equivalent to saying "destructors shouldn't have bugs". WELL OF COURSE THEY SHOULDN'T BUT GOOD LUCK WITH THAT.)

Re: C++ says “We have try... finally at home”

#75
post #25

Earlier quoted context omitted.

> Most of the languages that have finally clauses also have destructors. Hm, is that true? I know of finally from Java, JavaScript, C# and Python, and none of them have proper destructors. I mean some of them have object finalizers which can be used to clean up resources whenever the garbage collector comes around to collect the object, but those are not remotely similar to destructors which typically run determinist…

In C# the closest analogue to a C++ destructor would probably be a `using` block. You’d have to remember to write `using` in front of it, but there are static analysers for this. It gets translated to a `try`–`finally` block under the hood, which calls `Dispose` in `finally`. using (var foo = new Foo()) { } // foo.Dispose() gets called here, even if there is an exception Or, to avoid nesting: using var foo = new Foo(…

Java's is

    try (var foo = new Foo()) {
    }
    // foo.close() is called here.
I like the Java method for things like files because if the there's an exception during the close of a file, the regular `IOException` block handles that error the same as it handles a read or write error.

Re: C++ says “We have try... finally at home”

#76
post #53

Earlier quoted context omitted.

EDIT: I don’t think you can actually put a return in a defer, I may have misremembered, it’s been several years. Disregard this comment chain. It gets even better in swift, because you can put the return statement in the defer, creating a sort of named return value: func getInt() -> Int { let i: Int // declared but not // defined yet! defer { return i } // all code paths must define i // exactly once, or it’s a compi…

Huh, I didn't know about `return` in `defer`, but is it really useful?

No, I actually misremembered… you can’t return in a defer.

The magical thing I was misremembering is that you can reference a not-yet-defined value in a defer, so long as all code paths define it once:

  fn callFoo() -> FooResult {
    let fooParam: Int // declared, not defined yet
    defer {
      // fooParam must get defined by the end of the function
      foo(fooParam)
      otherStuffAfterFoo() // …
    }

    // all code paths must assign fooParam
    if cond {
      fooParam = 0
    } else {
      fooParam = 1
      return // early return!
    }

    doOtherStuff()
  }
Blame it on it being years since I’ve coded in swift, my memory is fuzzy.

Re: C++ says “We have try... finally at home”

#77
post #41
post #38

Earlier quoted context omitted.

I don't view finalizers and destructors as different concepts. The notion only matters if you actually need cleanup behavior to be deterministic rather than just eventual, or you are dealing with something like thread locals. (Historically, C# even simply called them destructors.)

There's a huge difference in programming model. You can rely on C++ or Rust destructors to free GPU memory, close sockets, free memory owned through an opaque pointer obtained through FFI, implement reference counting, etc. I've had the displeasure of fixing a Go code base where finalizers were actively used to free opaque C memory and GPU memory. The Go garbage collector obviously didn't consider it high priority to…

For GCed languages, I think finalizers are a mistake. They only serve to make it harder to reason about the code while masking problems. They also have negative impacts on GC performance.

Java is actively removing it's finalizers.

Re: C++ says “We have try... finally at home”

#78
post #70

I always wonder whether C++ syntax ever becomes readable when you sink more time into it, and if so - how much brain rewiring we would observe on a functional MRI.

It's very readable, especially compared to Rust.

I love how the haters of Rust's syntax can be roughly divided into two groups:

(1) Why doesn't it look like C++?

(2) Why does it look so much like C++?

Re: C++ says “We have try... finally at home”

#79
post #2

The submitted title is missing the salient keyword "finally" that motivates the blog post. The actual subtitle Raymond Chen wrote is: "C++ says “We have try…finally at home.”" It's a snowclone based on the meme, "Mom, can we get ? No, we have at home." : https://www.google.com/search?q=%22we+have+x+at+home%22+meme In other words, Raymond is saying... "We already have Java feature of 'finally' at home in the C++ refri…

That's why you shouldn't use memes in the titles of technical articles. The intelligibility of your intent is vastly reduced.

Re: C++ says “We have try... finally at home”

#80

I always wonder whether C++ syntax ever becomes readable when you sink more time into it, and if so - how much brain rewiring we would observe on a functional MRI.

It does get easy to read, but then you unlock a deeper level of misery which is trying to work out the semantics. Stuff like implicit type conversions, remembering the rule of 3 or 5 to avoid your std::moves secretly becoming a copy, unwittingly breaking code because you added a template specialization that matches more than you realized, and a million others.
Post reply on HN