8 ms·
Good stuff. Only compiler bugs I've seen in C++ have all been around exceptions. I think this is just another reason towards force-handled error codes. You don
by vvanders 10y ago
Good stuff.
Only compiler bugs I've seen in C++ have all been around exceptions. I think this is just another reason towards force-handled error codes. You don't have a whole new control flow that needs to be verified and is much simpler from an implementation/runtime perspective.
- jhasse 10y agoI think this would just move the bugs to the applications.
- vvanders 10y agoHence the "force-handled" part of my comment :).
- gizmo686 10y agoBut what you need is force-handled-correctly. If you think that programmers will correctly deconstruct partially constructed objects at every location where construction might fail, then you have far too much faith in our profession.
- wvenable 10y agoIt doesn't solve the problem because you'd have move to 2 stage construction/initialization and that creates even more problems than this.
- vvanders 10y agoNope, if you have an operation that can fail then wrap it in a type that represents that(I'm partial to Rust's Result<T,E>) then you force consumers to deal with potential errors and you can do 1-call construct + init if you want to. Exceptions cause all sorts of problems(like violating the principal of only paying for what you use). They aren't checked so you can't enforce handling via type system and in general they're just a mess in C++.
- Arnavion 10y agoC++ constructors can't return error codes or Result. That's the two-stage initialization (constructor call + initialize() call) wvenable is talking about. (Of course you could do the same thing as Rust and expose only a static creator function and hide the actual constructor.)
- vvanders 10y agoYeah, most projects I worked on was doing the static creator before Rust showed up on the scene since it sidesteps a lot of these issues.
- int_19h 10y ago> Exceptions cause all sorts of problems(like violating the principal of only paying for what you use). Exceptions are zero-cost in terms of performance on any sane architecture (this excludes x86, but not x64). The only cost that you're paying is the extra memory for the tables, which are all statically allocated.
- vvanders 10y agoDon't you need RTTI as well? That's not been zero-cost on all compilers I've used in the past.
- int_19h 10y agoYou do, but C++ includes RTTI separately from exceptions (dynamic_cast and typeid), so it's going to be there regardless. If you turn it off, then we're not talking about standard C++ anymore, but some subset.
- wvenable 10y agoWhen you throw and exception, C++ compilers add RTTI for those classes even when RTTI is separately disabled. You cannot call dynamic_cast and type_id but the generated code is the same. I don't really see this as much of an issue given you have to have this RTTI to catch the exception properly.
- hermitdev 10y agoA number of years ago, I hit against a GCC bug that generated an ICE (internal compiler error). Cause? Usage of an anonymous namespace in the global namespace. It was a short-lived regression, I think in the 4.1.2 series that came to me as a result of a supposedly minor OS update.
- user5994461 10y agoThat makes sense. Exceptions in C++ are a mess. It's completely platform, architecture, OS and compiler version specific. That's not well defined.
- metaobject 10y agoWhere in the C++ spec are implementations of features defined?
- int_19h 10y agoThe behavior of exceptions in C++ is well-defined. But implementations do have bugs about many things that are well-defined - this is one of those cases.
- pjmlp 10y agoOf course it is not defined, that is a language specification not a compiler implementation guide.
- Ace17 10y agoJust because a language feature is hard to implement doesn't mean we should abandon it. I'm not going back to explicit error handling.
- warmwaffles 10y agoCome on in, the water is fine. Handling errors without using exceptions is not that bad.
- geezerjay 10y agoIt's still very bad, though. Exceptions control that badness. There's no excuse to avoid using a useful feature for reasons that actually worsen your code.
- easytiger 10y agoException handling is computationally very very expensive when triggered. a cmp op costs nearly nothng.
- saurik 10y agoException handling costs absolutely nothing when not triggered (on most reasonably platforms these days, due to zero-cost exceptions), while that comparison instruction is still there, still taking its performance cost for every call of every function that could theoretically fail in the entire program.
- pdpi 10y agoIf it's a hot path, branch prediction will almost certainly make the cost of that comparison negligible though. If it's not a hot path, does it matter?
- sqeaky 10y agoThe difference in cost is negligible compared to the difference in correctness. Vtables are so optimized (and often elided) and caches so efficient and comparisons are cheap and branch predictors so great that the cost of both of these is functionally 0 in all code I touch outside the tightest inner in physics sims and rendering pipelines. Even there the differences is statistically negligible. On correctness, it is impossible to forget to deal with an exception, it is Tuesday when a C program forgets to check an error code. Did you know printf returns an error code? There are ways to force these returns to be checked by the compiler, but a language needs to be structured around it to be sane otherwise you wind up with every printf in an if statement. Forced exception checking is almost as burdensome, anybody with a few years of java ought to agree or at least see where I am coming from. Error handling is just plain hard. Only a few languages do it really well. I think either could be done right if baked in from the first language spec. But that is not where most code is written, most Java, C and C++ has to exist now. Clearly C has only error codes, and it has the most bugs. Java has exceptions and finally to force the dev to handle everything right there, which I think is a huge source of anti-patterns but better than error codes. C++ has exceptions and destructors which work the best of these, but still separate error handling from code execute all the time when it is only desirable most of the time.
- codedokode 10y agoI disagree. You are suggesting everyone should write error handling code manually rather than rely on compiler.
- deleted 10y ago[deleted]
- vertex-four 10y agoNot really. See Rust/Scala/Haskell's Result/Either type, which has compiler support, but that compiler support is lightweight - you use the same control structures and flows as with regular code.
- lmm 10y agoThat's a great approach, but needs sum types and HKT to be effective, neither of which C++ really has (std::variant exists but doesn't always behave as a proper sum type AIUI) at present.
- vertex-four 10y agoRust manages it without HKT quite reasonably (rather than implementing generic monads, it has the `?` operator, which is syntax-sugar for something like [0]), though sum types are a necessity. [0] match whatever { Ok(v) => v, Err(e) => return Err(From::from(e)) }
- lmm 10y agoAh, last I knew they were relying on macros. Still, ? is an ugly special case where with HKT it could be a reusable general operator.
- vertex-four 10y agoAbsolutely - there's currently discussion around a Carrier trait which would make it generic, once we have some variety of HKT. Still, it's good enough for now, and any future development of it will be backwards-compatible.
- josefx 10y agoBy that logic we should write hand optimized assembly. I think there was even a rant by Linus on GCC messing up the stack and he writes C. Clearly compilers shouldn't be trusted with important programs.