Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> you will eventually have C++ -> Rust -> C++ where the "inner" C++ throwing would be expected to cause the "outer" C++ to catch?

Look I hate to be that girl with the strong opinions on the orange website, but "goto is not an appropriate feature for an ffi" is a hill I'm ready to die on.



Exceptions are not “goto.” Exceptions are an example of “structured control flow” while “goto” certainly is not. Throwing an exception is an example of a “non local exit” which Rust also implements (in terms of “Return”).

Also the exception does not leak into rust-space. Like it or not, any serious c++ ffi must accommodate C++ exceptions, since that is a standard feature (not to mention idiomatic error signaling mechanism) in C++.


Exceptions are worse than go-to, they're a comes-from statement. At least with a go-to you know where you're going when you look at it -- with exceptions you could be coming from literally anywhere. All sorts of different control flows all filter into this one weird spot.

Exceptions are probably the worst thing in computer science.

This is a hill I'm happy to join AprilArcus on.


> exceptions you could be coming from literally anywhere.

False. exceptions can only come from throw statements, which are both static and finite within every codebase.

> Exceptions are probably the worst thing in computer science.

Opinion, irrelevant.


> False. exceptions can only come from throw statements, which are both static and finite within every codebase.

Not between libraries and library customers. From the perspective of the library author, the set is dynamic and uncountable, and similarly from the perspective of the library customer, any exceptions thrown are dynamic and uncountable.

> Opinion, irrelevant.

It's almost like opinions come from some basis worth exploring instead of outright rejecting without consideration. In my (obviously irrelevant) opinion, you may grow as a person if you learn to explore the opinions of others :)


That's ridiculous, exceptions always come from further down the stack and can whose throw location can be precisely identified with basic debug symbols.


Indeed, and that is orders of magnitude harder to reason about than something that can only come from a specific invocation.


> Throwing an exception is an example of a “non local exit” which Rust also implements (in terms of “Return”).

They are not isomorphic. Return always hands control back to the caller; you can emerge from an exception inside any arbitrarily higher scope, and the proliferation of weird edge cases (what happens when I throw an uncaught exception in a constructor or destructor, the exception safety guarantee hierarchy) are good evidence for why this behavior is too complicated for its own good.

> Like it or not, any serious c++ ffi must accommodate C++ exceptions

Obviously this is the case and I'm not trying to say otherwise. I already said so upthread, but it seems to me that the least complicated way to do so is to wrap wrap foreign C++ function return values in a Result<T> (unless they can be statically proven not to throw), and report errors to C++ through some kind of Either-ish box. Then the C++ caller can decide whether they want to handle the error then and there, or throw an "idiomatic" exception.


>> Throwing an exception is an example of a “non local exit” which Rust also implements (in terms of “Return”).

> They are not isomorphic.

It was never claimed that “return” and “throw” were isomorphic. Only that they are both examples of non-local exits.

> good evidence for why this behavior is too complicated for its own good.

That’s a nice opinion but I wouldn’t consider that evidence except under the loosest definitions of the word. By the same reasoning I could claim that being able to invoke “return” at any arbitrary point in the function is evidence that return is a complicated feature.

Just like “return” exceptions in C++ have a statically defined set of areas they can branch to and the invocation of throw is well defined w.r.t. to object cleanup. Admittedly those landing sites are more numerous than “return” but not different in their more defining properties.


> I could claim that being able to invoke “return” at any arbitrary point in the function is evidence that return is a complicated feature.

Not really, because a return statement (like a go-to) only has one place to go. An exception has an unlimited number of places to come from. That put it into its own special circle of hell.


Your metric of what makes a language feature too complicated is just as arbitrary as mine.

> An exception has an unlimited number of places to come from

False. An exception can only come from a throw statement, which is both lexical/statically defined and finite in number within every codebase.


> False. An exception can only come from a throw statement...

Obviously.

> ...which is both lexical/statically defined and finite in number within every codebase.

Not in every case. Any time you have a library that calls into client code the set is dynamic and uncountable from the perspective of the library author.


Tons of C++ FFI is really C FFI (with maybe some lightweight wrappers) and completely ignores exceptions, leaving them to the end user to manually mangle.

On the flipside, any serious gamedev C++ FFI must accomodate exceptions-disabled environments, since that's common in gamedev codebases - and even the default settings on at least one relatively modern gamedev platform.


> On the flipside, any serious gamedev C++ FFI must accomodate exceptions-disabled environments

Any C++ ffi that accommodates exception also accommodates exception-disabled environments by virtue of accommodating function calls. Certainly AutoCXX accommodates codebases that use exceptions as well as those that disable exceptions by convention.


> Certainly AutoCXX accommodates codebases that [...] disable exceptions by convention.

From the documentation, it sounds like that's only true if you eschew Result, the absolute backbone of not-automatically-unwinding Rust error handling.

You could presumably, technically, roll your own Rust struct/enum - "NonStdResult" - and expose that to C++ however cxx deigns to expose Rust enums to C++. But that seems... very awkward at best, to completely counter to the entire point of AutoCXX - in trying to eliminate the need to write a bunch of special case conversion boilerplate - at worst. If you're suggesting that as a superior design choice, we're seriously going to have to agree to disagree.


How is goto related to dynamic stack unwinding?




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: