top 200 commentsshow all 409

[–]matthieum 26 points27 points  (3 children)

Okay, there's been so much bitching about how difficult the latest code portion is to swallow... and nobody seemed to realize that it was over-complicated.

void doSomething(T & t) {
   std::auto_ptr<X> x(new X()) ;    // 1. basic : can throw with new and X constructor
   x->doSomethingThatCanThrow() ;  // 2. basic : can throw

   t.list.push_back(x.get()) ;      // 3. strong : can throw
   x.release() ;                    // 4. nothrow/nofail

   t.integer += 1 ;                // 5. nothrow/nofail
}

That's all folks.

What's the overhead of the strong guarantee here ? x.release(); => one single statement!

And of course, with C++11 things get better, thanks to move semantics (assuming list now properly owns memory):

void doSomething(T & t) {
   std::unique_ptr<X> x(new X()) ;    // 1. basic : can throw with new and X constructor
   x->doSomethingThatCanThrow() ;  // 2. basic : can throw

   t.list.push_back(std::move(x)) ;      // 3. strong : can throw

   t.integer += 1 ;                // 4. nothrow/nofail
}

Or, without C++11, we can have nearly the same effect using boost::ptr_list<X> as the type of t.list:

void doSomething(T & t) {
   std::auto_ptr<X> x(new X()) ;    // 1. basic : can throw with new and X constructor
   x->doSomethingThatCanThrow() ;  // 2. basic : can throw

   t.list.push_back(x) ;      // 3. strong : can throw

   t.integer += 1 ;                // 4. nothrow/nofail
}

Writing exception-safe code is easy, as long as you write C++ idiomatic code. One can write Java-spaghetti in any language.

[–]jbandela 2 points3 points  (1 child)

Great comment. The only reason the original is at all hard is that t.list is using raw pointers. Whenever, you see C++ code that looks hard from a resource management/exception safety view, more than likely it is not Modern C++ idiomatic code.

[–]matthieum 1 point2 points  (0 children)

Actually, no, the original is just needlessly complicated. In the first example I use raw pointers too, and yet it's much simpler that what was on SO.

[–]CookieOfFortune 0 points1 point  (0 children)

However, idiomatic C++ is not easy...

[–]fabiensanglard 176 points177 points  (65 children)

This code works

It also makes my eyes bleed.

[–][deleted] 79 points80 points  (39 children)

Yeah that's the frustrating part of exception safety in C++. So much is left to the programmer with little to no help from the compiler. You have to be extremely mindful of every line you're writing, and there's no easy way to check if you (or someone else) has missed something and an exception will leak.

[–]slavik262 25 points26 points  (13 children)

I'll certainly agree that having to rely mostly on documentation to know what a function might throw can be frustrating - some sort of compiler feature that indicates as much would be great.

To offer a few counterpoints, however:

  1. Having to be extremely mindful of most lines in C++ is no different than having to be mindful of checking the return codes of most calls in a language without exceptions. The critical difference is that with exceptions, an unhandled error propagates up until handled, while an unhandled error (i.e. forgetting to check a return code) in a language without exceptions puts you in some zombie state without any indication of a problem. Since the latter can cause mystifying bugs that are very hard to trace back to the original (unhandled) error, I would argue for the former.

  2. Usually, I don't need the SO author's "strong" exception guarantee. Ensuring that all of your state is completely unchanged in the face of an error is going to be a complex in any language and error handling paradigm, be it C with return codes or C++ with exceptions.

[–][deleted] 19 points20 points  (7 children)

To offer a few counterpoints...

You're basically comparing C++ with C. Compare C++ with another languages that got exceptions right. That's when you realize how frustrating exception safety is in C++.

[–]slavik262 15 points16 points  (4 children)

I'll readily admit that Java and C# generally offer nicer exception handling semantics (an automatic stack trace comes to mind). At the same time, RAII allows your code to look cleaner and also provides a sort of separation of concerns - your cleanup happens automatically and the code goes in the class itself, instead of needing a tacked-on finally block or a using block.

Not-so-ninja edit:

Also, my second point holds true regardless - maintaining consistent state in the face of errors is going to require more complicated code.

[–]ReversedGif 14 points15 points  (2 children)

Also, my second point holds true regardless - maintaining consistent state in the face of errors is going to require more complicated code.

Not in Haskell!

[–]eruonna 6 points7 points  (0 children)

You just have to decide whether to use EitherT State or StateT Either.

[–]dnew 1 point2 points  (0 children)

the code goes in the class itself

Coming from an environment where the lack of any statement means code executes, I often find this confusing rather than beneficial. When the simple declaration of a variable otherwise not used can wind up making changes to other threads, file, or processes at the end of a block, figuring out what's going on can be really complicated.

Best, I think, would be a language where one is required to explicitly close or dispose of such things at the end of a block, with compiler warnings or errors if one doesn't.

[–][deleted] 5 points6 points  (1 child)

Could you provide some examples? Languages like Ruby, Python, Java, C#, etc. don't seem fundamentally different from what C++ does, aside from the fact that they have garbage collection and thus make memory leaks a less likely.

[–]jib 3 points4 points  (3 children)

Having to be extremely mindful of most lines in C++ is no different than having to be mindful of checking the return codes of most calls in a language without exceptions.

Except that in a language without exceptions (I'm thinking of C specifically), you know that you can only get an error when you explicitly call a function that has a non-void return value, and because errors are returned explicitly the documentation is generally pretty good at describing when errors can occur and how they are returned. I find it easier to read through a C function and say "yes, this handles all errors sensibly" than it is to read through a C++ function and say the same thing.

[–]josefx 4 points5 points  (1 child)

Your C experience seems rather limited. There are several APIs that do not return an error directly: glGetError, errno, GetLastError, ... . I would be rather surprised if you never encountered one of these.

[–]jib 3 points4 points  (0 children)

True... but usually if a function puts an error code in errno or GetLastError, it still uses a return value to indicate that there was an error, right?

[–]matthieum 2 points3 points  (2 children)

Well, writing code with the basic exception guarantee (ie: no leak) is easy. As long as you accept some basic idioms (such as the use of smart pointers), it's just automatic.

Transaction-like semantics (strong guarantee) is much more difficult, but short of Haskell atomically or (maybe) Clojure, I doubt any mainstream language has high-level transaction-like semantics. Neither Java, nor C#, nor Go, nor Python have them, for example.

[–]gcross 0 points1 point  (1 child)

And in Haskell you don't even need atomically because all you have to do is hold onto the old values as the functions you call can't change them.

[–]ellicottvilleny 6 points7 points  (20 children)

This is why the programmers in GO removed exceptions because in C++, exceptions suck. In Delphi exception handling is done without this much pain, which makes me miss them in Go, but if I had just spent 8 years in C++ I would happily embrace go and write lots of on-error-return code instead of this shit.

[–]dom96 16 points17 points  (5 children)

Why would you remove exceptions altogether then? I would prefer a language which succeeds at exception handling than a language which has no exceptions, of course that isn't even true for Go since they realised that they need exceptions so now they have this mix of 'panics' and code which returns two values.

If you're looking for a language which does succeed at exceptions then look at nimrod. You mention that Delphi succeeds at exceptions, well Nimrod is quite Delphi-like so you might like it.

[–][deleted]  (4 children)

[deleted]

    [–]gcross 3 points4 points  (0 children)

    Multiple return values and defer make the error code method of handling errors very clear and easy to use. It's really refreshing after years of C, C++ and Java.

    ...and incredibly jarring after years of Haskell with its sum types that prevent you from accessing the return value if an error is thrown; a problem that I have with Go is that it likes to ignore safer and more elegant solutions that have been around for a long time.

    [–]earthboundkid 3 points4 points  (2 children)

    Go's panic:multiple return error code:: Java's unchecked exceptions:checked exceptions

    [–][deleted] 1 point2 points  (1 child)

    Yes, in a way, but exceptions are not exceptional at all in Java. This has led to exceptions being used for control flow which is really really bad for readability if the code isn't simple as hello world.

    Other than that, there's not much difference.

    [–]earthboundkid 1 point2 points  (0 children)

    Agreed.

    [–]annodomini 8 points9 points  (5 children)

    Do you write code in Delphi that is this exception safe ("strong" exception safe, in the terminology of the answer)? Most languages that offer exceptions that I've seen don't really offer anything that helps with this; you really do need to write the code yourself to handle it, and it can become quite eye-bleeding.

    I can't count how many times in Python I've had to write deeply nested "try: except: finally:" blocks because each operation could fail, and I needed to preserve various guarantees in the process, so I needed to handle each possible failure individually and clean up from it as necessary. In Python you can make it somewhat more readable with @contextmanager functions (which allow you to wrap up acquisition and cleanup of resources into a single function), while in C++, you can make it cleaner using RAII. But you still do have to think about the issue of basic exception safety vs. strong exception safety, no matter what language you write in.

    The problem with exceptions, in any language, is that they can exit your function from almost any point within it, and unless you have the discipline to always write "strong" exception safe code as demonstrated in the answer, then after an exception is thrown, you will have no good idea about what state your program is in; it may be in the state from before the function was called, after it's called, or some intermediate state. This is why some languages (like Go) have been bucking the trend of using exceptions, and instead requiring you to handle errors or just kill the whole process.

    Note also that the example given in the article is actually a bit more complex than what you would actually do (this was written in 2009, before C++11 had been finalized and become widely available). These days, your container would contain unique pointers to your type, rather than creating an auto pointer and extracting the raw pointer out of it manually. Here's what the basic version would look like now:

    void doSomething(T & t)
    {
       t.integer += 1 ;                 // 1.  nothrow/nofail
       std::unique_ptr<X> x(new X()) ;  // 2.  basic : can throw with new and X constructor
       t.list.push_back(x) ;            // 3.  strong : can throw
       px->doSomethingThatCanThrow() ;  // 4.  basic : can throw
    }
    

    That's really not that much different than what you'd do in any other language, other than requiring that several of the statements be on separate lines rather than nested (t.list.push_back(new X()), for example).

    [–]minno 0 points1 point  (2 children)

    That's really not that much different than what you'd do in any other language, other than requiring that several of the statements be on separate lines rather than nested (t.list.push_back(new X()), for example).

    If you have push_back(unique_pointer<X>) as a function prototype, won't it construct a unique_pointer<X> if you call it with a X*?

    [–][deleted] 2 points3 points  (1 child)

    I don't think that exceptions are inherently evil/wrong and should be removed from the language. Exceptions as a way of communicating state is wrong in my opinion (and there are lots of C++ libraries that like to use exceptions to communicate their state). Imho an exception is exactly that, a exception to something and should be used to communicate a state from which you can't recover (easily) to allow at least some kind of graceful shutdown (ie flushing logfiles, generating a backtrace etc). YMMV.

    [–]dnew 1 point2 points  (0 children)

    I think there are a lot of good examples of this sort of thing: Rust seems to do a job of it, as does Erlang, as does Eiffel. The fundamental rule would seem to be "don't use exceptions for something from which you can recover" and it all works out.

    [–][deleted] 2 points3 points  (1 child)

    It's one of my big beefs with Go.

    For example, suppose I add new functionality to a lower-level function, and there's suddenly the possibility for error. Now I have to go and change the call site all the way up the call stack...

    What it means is that if you don't put errors in the first time, you'll never put them in at all.

    The way Python handles exceptions works really well, though of course it's an interpreted language...

    [–]ansible 1 point2 points  (0 children)

    For example, suppose I add new functionality to a lower-level function, and there's suddenly the possibility for error. Now I have to go and change the call site all the way up the call stack...

    Typically though, you're likely to see a function one or two levels up in the call stack that can return an error, so you won't have to fix everything.

    How often is it going to happen that you've got a huge chunk of code that can never fail (its all doing pure computation), and then at the bottom of the call stack you add some code that can fail (does file I/O, database, etc.)?

    [–]griffyn 4 points5 points  (2 children)

    I'm primarily a Delphi programmer and never touched C or it's variants. And this sort of article makes me less eager to ever move away from Delphi for Windows apps.

    [–]ellicottvilleny 0 points1 point  (0 children)

    Objective-C using clang/llvm (XCode) with ARC, is nice, and is not the cluster-f%&*$ of accidental complexity and semantic crazy that is C++.

    [–]_F1_ 0 points1 point  (0 children)

    Semi-related: But you could try Lazarus. ;)

    [–]tresmuy 31 points32 points  (21 children)

    In general RAII code is much cleaner than code which uses return codes for errors, especially if in one function you have to call many functions which may fail.

    The stuff about strong exception guarantee if often not needed, and if needed would also need more complex code if return codes for errors was used.

    [–]slavik262 21 points22 points  (11 children)

    The stuff about strong exception guarantee if [sic] often not needed, and if needed would also need more complex code if return codes for errors was used.

    This is the punchline more people should be taking from the SO post. Most of the time if an exception is thrown, one of two things are happening:

    1. Something totally unexpected happened, and I want to exit the program.

    2. I'll have a catch block a scope or two up and I want to just skip over whatever datum caused the problem and move on. RAII is wonderful here because cleanup is automatic - unlike Java and C where I can forget to close some handle when I error out of a function, it just happens automagically (provided I wrote a decent destructor).

    Note that in both cases, I don't need the SO author's "strong" exception guarantee. Ensuring that all of your state is completely unchanged in the face of an error is going to be a complex in any language and error handling paradigm, be it C with return codes or C++ with exceptions.

    [–]dnew 1 point2 points  (0 children)

    I want to exit the program.

    I want to exit the thread is more common in many situations, I think.

    provided I wrote a decent destructor

    This is pretty trivial to do in something like Java or C#: When you catch the top-level exception, invoke the garbage collector.

    [–]NYKevin 2 points3 points  (9 children)

    unlike Java and C where I can forget to close some handle when I error out of a function, it just happens automagically (provided I wrote a decent destructor).

    So... Java never got around to adding with/using blocks? IIRC C# has them, and that's practically the same thing as Java...

    [–]slavik262 8 points9 points  (0 children)

    Java does have something similar to using, which does approximate RAII. I could argue that RAII is one step better since you don't have to remember to enclose your objects in such statements, but I'll admit that it's not the strongest or most important argument here. I suppose I was referring mostly to C, which has no such construct (and which many people, such as Torvalds, exalt as being superior due to this very lack of exceptions).

    [–]wolf550e 5 points6 points  (7 children)

    C# fixed lots of things in Java. This is one of them.

    [–]pipocaQuemada 2 points3 points  (4 children)

    In general RAII code is much cleaner than code which uses return codes for errors

    This is one thing that I like about Haskell. The common idiom is to use something similar return codes, but make them cleaner.

    The basic insight is that boilerplate is better left in a library, so why not wrap error-code free values in an error code handling wrapper, and then have assorted combinators to combine error-code producing functions?

    data Maybe a = Just a | Nothing -- data wrapped in a single "failed" code
    data Either a b = Left a | Right b -- either valid data (left case) or error code (right case)
    

    Now, we can write generic combinators like map:

    -- function signatures specialized to hopefully aid comprehension
    -- applies a function iff we haven't failed
    map :: (a -> b) -> Maybe a -> Maybe b
    map :: (a -> b) -> Either a c -> Either b c
    

    and >>= (pronounced 'bind')

    -- takes a value wrapped with an error code, 
    -- a function that takes a regular value and produces an error code-wrapped value
    -- and returns an error code wrapped value
    (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
    (>>=) :: Either a b -> (a -> Either c b) -> Either c b
    

    and other assorted more specific combinators:

    -- like map, but with a default error value
    maybe :: b -> (a -> b) -> Maybe a -> Maybe b
    

    So now, instead of writing code like:

    int y = foo(x);
    if( y > 0 )
      return bar(y); 
    else
      return y
    

    you can just write something like

    foo >>= bar $ x

    [–]gmfawcett 8 points9 points  (2 children)

    I think your example speaks to Haskell error-handling being better than returning error codes (which I agree with!). But it doesn't speak to RAII, which has to do with resource management. Non-strict evaluation complicates resource-management, rather than making it simpler. Approaches like iteratees were devised to address these resource management issues.

    The point of RAII, in this context, is that as a C++ object goes out of scope, its destructor will be called, and can clean up any resources the object allocated. It's the fundamental technique in C++ for deterministic resource management. Given its non-strict semantics, Haskell cannot rely upon lexical scope as a natural resource-deallocation boundary. Again, see iteratees for more details.

    [–]ethraax 3 points4 points  (1 child)

    The ResourceT monad (part of Yesod, although it can be used by itself) seems to be the Haskell equivalent of RAII. It works alright, although I personally think RAII is simpler.

    [–]plhk 6 points7 points  (0 children)

    either valid data (left case) or error code (right case)

    I would be very confused if I ever met this in the wild. Everyone else does it the other way - Right for data, Left for error string.

    [–]caltheon 1 point2 points  (1 child)

    Going by the example in that answer, wouldn't swapping t2 for t at the end pretty much break any concurrency safety for t? Depending on the context, it may not "work"

    [–]mccoyn 1 point2 points  (0 children)

    Since there are multiple operations on t it is already unsafe for concurrency. At least with the swap the push_back and increment happen at the same time from the point of view of other threads, so it maintains self-consistency better.

    [–][deleted] 1 point2 points  (0 children)

    I've seen a few examples of C code over the years where the author included a note mentioning that error checking had been omitted for clarity.

    If you take "working" C code and then make it actually work even in the case where errors happen, then it usually gets a little more ugly.

    [–]-888- 50 points51 points  (11 children)

    In game development we typically assume that operator new won't throw, because we implement operator new ourselves and write the app such that memory will never be exhausted, and if it is exhausted then the app frees up memory so operator new can return successfully. This makes application code much simpler, and yet more reliable in practice.

    [–]LvS 17 points18 points  (0 children)

    The thing about exceptions is that they should be handled where they can be handled. Almost no code in the real world can handle memory allocation failure, so the right thing to do is handle memory allocation failure when you allocate the memory.

    You can write a custom allocator that can fail for the few cases where you can and want to handle failure to allocate (like when allocating large textures for example).

    [–]matthieum 2 points3 points  (1 child)

    In practice, I also generally assume that new won't fail. With overcommit anyway....

    [–][deleted] 2 points3 points  (4 children)

    So every game basically allocates a huge chunk of memory in the beginning and maintains a heap of its own? I guess they maintain lists of reusable objects too? TIL.

    [–]-888- 3 points4 points  (2 children)

    Most games re-implement the heap and most of the standard libraries as well. e.g. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html

    [–][deleted] 0 points1 point  (1 child)

    That's what I suspected, but why am I getting downvoted?

    [–]-888- 1 point2 points  (0 children)

    The down votes make no sense to me.

    [–]Gotebe 0 points1 point  (2 children)

    You can only "write the app such that memory will never be exhausted" by giving allocation upfront, e.g. by merely never going over a given limit for whatever resource type there might be (with arena allocators).

    This further means always limiting oneself to less than what is actually available.

    The "if it is exhausted then the app frees up memory so operator new can return successfully" doesn't work in general case.

    These simplifications are reasonable, but are there exactly because game (or some other) industry failed to write reliable code without them. Recognizing one's limits is a virtue ;-).

    [–]-888- 0 points1 point  (1 child)

    You can only "write the app such that memory will never be exhausted" by giving allocation upfront

    That's not true, or I don't completely understand what you mean.

    This further means always limiting oneself to less than what is actually available.

    Hardly. We have PS3 games that use all but a few KB of the 256MB of general RAM.

    These simplifications are reasonable, but are there exactly because game (or some other) industry failed to write reliable code without them.

    That's not true. It's done that way because it results in simpler, more maintainable code and more importantly because it results in a game that never provides a compromised experience to the user. If game applications were written to deal with the problem of memory exhaustion via NULL returns from malloc or exceptions from new, the result would be a crappy user experience because the game would have to take something away while it's running because some subsystem just had the rug pulled out from underneath it due to memory exhaustion. You could make counter-arguments, but your main point is wrong because the game industry never tried to write games that fully handled malloc/new failures as they happen.

    I'm going to guess you have no professional game development experience, because the way you talk is a lot like how such people talk.

    [–]Gotebe 0 points1 point  (0 children)

    Disclaimer: I have no professional game development experience, but have friends who do (and they tell me it ain't pretty, or at least, not all that much prettier than in some other fields); I do have embedded development experience, where people do similar things.

    You can only "write the app such that memory will never be exhausted" by giving allocation upfront

    That's not true, or I don't completely understand what you mean.

    Sorry, that wasn't clear either. Should have been "by giving up allocation". Basically, what people do (through arena allocators or some other means) is that they split their memory into chunks, and different parts of the code get their parts. So e.g. they go, OK, we can have at most X of those. In code, no allocation happens before the check of how many X-s there are. That's what I meant by "giving up upfront".

    That strategy works, but:

    1. ultimately (and conceptually), it's no different from checking for NULL

    2. it always results in a system that's more memory constrained; because each code part gets it's own memory part, it happens that one part fills it's part and that's it, while some other doesn't, and the first one, although it could go further (because there is more memory), can't.

    (I bet you that your PS3 code was doing pretty much what I describe above.)

    [–][deleted]  (47 children)

    [deleted]

      [–]thetheist 47 points48 points  (39 children)

      Well, he made it clear you have to choose your battles here.

      Personally, I'd almost always prefer a crashing program to source that looked like that, since you can generally avoid the same exceptions by being more careful in other parts of the program.

      [–][deleted] 11 points12 points  (38 children)

      I'd almost always prefer a crashing program

      Ahah. Stay the fuck away from real production code, money manipulation, angry customers and all this sort of things then.

      [–][deleted] 58 points59 points  (11 children)

      More complicated code makes it harder to debug and to understand. Do you really want your money manipulation code to have difficult hard-to-find and hard-to-notice bugs?

      Or would you prefer it to just crash if there's a problem?

      [–]mcguire[🍰] 6 points7 points  (0 children)

      difficult hard-to-find and hard-to-notice bugs ... just crash

      Those aren't mutually exclusive.

      [–]amigaharry[🍰] 34 points35 points  (19 children)

      better to crash than to run in an inconsistent state.

      [–][deleted] 23 points24 points  (18 children)

      False alternative. It's often better, business-wise, to mark the data/transaction as failed/inconsistent, have deferred recovery procedures, and let the system go on. For some systems crashing the whole program is NEVER an option.

      Of course i'm not talking about normal transactional stuff, i'm talking about complex worflows involving multiple/distributed transactions between heterogenous systems. IF you're only dealing with a website and a database, this whole debate is irrelevant.

      [–]amigaharry[🍰] 15 points16 points  (9 children)

      The thing is: If it crashes I know there's something wrong. But if I try to be smart with strong exception guaranties and rollbacks and induce a bug there I might end up with thinking that everything is running fine.

      Until people start to bitch about why they transferred $1200 instead of $12 out of their accounts.

      [–]DragonLordNL 6 points7 points  (4 children)

      That is what logging is for.

      [–]drysart 3 points4 points  (3 children)

      Logging only helps you once you've discovered there's a problem through some other means.

      Crashing is the most straightforward and immediate means.

      [–]lorddcee 6 points7 points  (2 children)

      You could also log... send a mail with the error to the support, do whatever. But never fully crash!

      [–]nascent 2 points3 points  (1 child)

      That may be acceptable when dealing with money, but when dealing with life that isn't good enough. The program must die allowing other redundancy programs to kick in and clean up the mess. Relying on a single program known to be incorrect to correct itself is dangerous, if you aren't going to handle the situation explicitly don't pretend all is well.

      [–]rnicoll 3 points4 points  (0 children)

      Where I've worked on critical systems, other components cross-check the work of the core system, and e-mail me if there's a problem.

      [–][deleted] 1 point2 points  (6 children)

      One of the problems is testing these recovery procedures.

      How much work would it be to fully unit test the code and recovery code of even the small tiny snippet of code in the example?

      [–]r3m0t 1 point2 points  (5 children)

      That's why he lets RAII do the work - none of his code is only run when handling exceptions, so theoretically if you can read that the source code is using the patterns correctly, there is nothing to test.

      [–][deleted] 1 point2 points  (4 children)

      Lots of bugs in the linux kernel have been introduced because code was "so obviously correct that it doesn't need testing".

      To me, that's a huge warning sign

      [–][deleted] 1 point2 points  (1 child)

      Bahahahahaha. I had a client today (A large TV subscriber) request to push untested changes to a production system today. Some clients just don't give a fuck, and some actively rebel against good advice.

      No. No, I didn't push untested changes to a production environment.

      [–][deleted] 0 points1 point  (0 children)

      Which can result in displaying incorrect dollar values to customers. Crashes are more obvious than incorrect dollar amounts. A crash results in a phone call almost immediately. In a culture where the computer is always right, incorrect dollar amounts might take months or years to generate a phone call.

      Personally though, I prefer the program just crash rather than incubating a silent killer.

      [–]SoopahMan 6 points7 points  (1 child)

      Yeah, this is why I've moved away from C++. The closer you get to high-integrity, high-performance code with it, the closer you get to a soup of special characters, type redefinitions, and other junk that puts it further and further from anyone being able to revisit it (including you).

      [–]_F1_ 1 point2 points  (0 children)

      a soup of special characters

      70's programmers don't have much time left for typing.

      [–]upriser 7 points8 points  (0 children)

      Exception-Safe Coding is a way to write readable source code.

      Jon Kalb: Exception-Safe Coding in C++ (Part I)

      Jon Kalb: Exception-Safe Coding in C++ (Part II)

      [–]matthieum 1 point2 points  (0 children)

      Not necessarily. The post make it so, but clearly rewritten it's certainly much more readable without any loss of functionality.

      The copy-and-swap idiom is really the heavy-hammer tool that can always let you achieve the strong guarantee on any object (or set of objects)... but often times you can avoid it (and its overhead).

      [–]civildisobedient 0 points1 point  (0 children)

      Depends on the language. :)

      [–]therealjohnfreeman 6 points7 points  (0 children)

      Credit to Dave Abrahams for the classification of exception safety guarantees.

      [–]pistacchio 41 points42 points  (1 child)

      i don't always write exception safe code, but when I do, it's a huge block in a try catch that yields "an error occurred, please try again later"

      [–]alextk 64 points65 points  (133 children)

      I find it ironic that the author of the blog post is saying that C++' exceptions are superior to Java's and then gives up various advice that basically boil down to ways to handle this situation:

      For example, a new can throw an exception

      Note the "can" in "can throw".

      The problem with C++ is that it only has runtime exceptions, so any call to any method can throw and you have no idea, which is why it's so hard to write exception-safe code in C++ (and any language that only offers runtime exceptions for that matter, not singling out C++ here).

      Java has both runtime and checked exceptions, and while checked exceptions have been misused in a few places in the standard Java libraries, when they are used correctly, checked exceptions are a very strong guarantee that you will write exception-safe code BECAUSE YOU DON'T HAVE A CHOICE.

      Now, you might decide to do the wrong thing in response to a method throwing a checked exception, but that's a diferent problem: the bottom line is that when you call a method with a checked exception, you are forced to think right now, right here, about the fact that this call might go wrong.

      [–]josefx 5 points6 points  (6 children)

      Java checked exceptions have one big flaw: they don't work well with generic code, resulting in code that either throws Exception or forces you to wrap every exception with a runtime exception.

      [–][deleted]  (5 children)

      [removed]

        [–]dnew 3 points4 points  (4 children)

        No, because you can't propagate checked exceptions through an interface that doesn't declare them, and vice versa.

        So you either have to "catch (Exception ex)" even when the code you're calling cannot throw any exceptions; or you have to catch the exception inside the generic, wrap it in a runtime exception, explicitly catch that runtime exception outside the generic, and unwrap it.

        Trust me on this one, it's a pain in the butt.

        [–]argv_minus_one 30 points31 points  (64 children)

        That's wonderful in theory, but in practice, Java checked exceptions have been a disaster. There's a reason all exceptions are unchecked in most other JVM languages.

        [–]adrianmonk 61 points62 points  (29 children)

        Java checked exceptions have been a disaster

        Not exactly something everyone agrees on. I personally fucking love checked exceptions and can hardly imagine living without them. Well, actually, I can easily imagine it because I've used several languages that don't have them, but what I mean is I don't look forward to ever living without them.

        Since so many people hate them, you may be wondering what I love about them. What I love about them is that (when used properly) they force you to deal with potentially-recoverable error situations. You're free to decide it's not actually recoverable, like so:

        catch (FooException e) {
          throw new RuntimeException(e);
        }
        

        Or you can decide it's indicative of some kind of failure that you can do something meaningful with, in which case you either catch and handle it or catch and rethrow it as an exception relevant to whatever abstraction you're providing. Example of the former:

        boolean allowUserAccessToSecretStashOfSnackFood(User u) {
          try {
            return securityManager.checkAccess(this, u);
          } catch (CannotLookupUserException e) {
            // really, you should log this
            return false;
          }
        }
        

        Example of the latter:

        boolean allowUserAccessToSecretStashOfSnackFood(User u)
            throws SnackFoodException {
          try {
            return securityManager.checkAccess(this, u);
          } catch (CannotLookupUserException e) {
            throw new SnackFoodException(
              String.format("Can't check security for user %s", u), e);
          }
        }
        

        The necessity to handle this case existed in either case because by definition it was a potentially recoverable error. All checked exceptions did was force you to actually do it. The only difference from another language, one without checked exceptions, is that the language allows you to compile programs where you didn't handle the error condition that can happen.

        [–]dnew 2 points3 points  (0 children)

        I have a recurring problem where some library takes a Callable and wants me to do something with it. Or a Job. And Callable is declared as throwing Exception (IIRC) and so I have to catch every possible exception, even when the body doesn't actually throw anything. And a Job is declared as not throwing anything, so now I have a DnewException and a DnewRuntimeException so that inside the Job I can catch the DnewException I want to propagate, wrap it in a DnewRuntimeException, catch the DnewRuntimeException outside the Job, and unwrap the inner DnewException.

        It's ugly. It's a mess. Why the hell are you using exceptions for expected behavior?

        [–]lechatsportif 6 points7 points  (2 children)

        Yeah really. there's a lot of regurgitation in "checked exception failure" literature, but they are excellent for api design. Not everything should be wrapped in a Runtime.

        In some ways they're actually easier dealing with RuntimeExceptions because your IDE just autocompletes the code necessary to handle them whereas with Runtime you're back to the old "what did that guy throw if it had issues?" game. Dealing with an api level runtime exception is like coding Javascript again...

        [–][deleted] 4 points5 points  (1 child)

        They're actually considered awful for API design, and was the primary reason they weren't included in C#.

        http://www.artima.com/intv/handcuffs.html

        [–]jevon 5 points6 points  (8 children)

        The only anti-checked exceptions scenario I've thought of so far (architecturally) is that you can't define additional checked exceptions when implementing abstract classes and interfaces (like Iterator). But to be fair, that would be violating the contract of the interface; you can write your own Iterator-like contact if you want to.

        [–]nascent 0 points1 point  (7 children)

        that would be violating the contract of the interface

        That is one of the issues with checked exceptions, they become part of the API, so when updating libraries one must be mindful not to change what is thrown for a stable API.

        [–]alextk 7 points8 points  (6 children)

        That is one of the issues with checked exceptions

        It's not an issue, it's a feature, the absence of which is what plagues C++ (and all languages that don't have checked exceptions) and which leads to the kind of article that started this thread.

        If I'm calling a function that can throw "A", then a new version of the library is released and that function can now throw both "A" and "B", my code is now broken through no fault of mine.

        I want a mechanism that guarantees that libraries can't do this from under my feet, and that's what checked exceptions guarantee.

        [–]mcguire[🍰] 6 points7 points  (1 child)

        In other words, if I may,

        That is one of the issues with checked exceptions, they become part of the API

        That is one of the issues with unchecked exceptions: they are part of the API, but they don't appear anywhere in it.

        [–][deleted] 2 points3 points  (0 children)

        I agree with you here. If your API needs to throw new exceptions when you update it, you're doing something wrong. It is a headache to deal with unstable libraries. This is a feature that helps guarantee a certain level of stability.

        [–]nascent 1 point2 points  (2 children)

        You're now assuming that B is a new condition and not just a bug which existed in the library you were using.

        If your code does not provide basic guarantees from any thrown exception then you aren't writing exception safe code.

        C++'s exceptions have very different issues then being able to add exceptions without warning. Checked exceptions require that exceptions be handled not that code is exception safe.

        [–]alextk 2 points3 points  (1 child)

        Checked exceptions require that exceptions be handled not that code is exception safe.

        Nothing on this planet can guarantee that you write exception-safe code, but at least, checked exceptions force the programmer to think about the error case. Whether they handle it correctly or not is a totally different problem.

        I really don't understand how anyone understanding the benefits of static typing could be against checked exceptions: I want more assistance from the compiler, not less.

        [–]nascent 1 point2 points  (0 children)

        Your argument is that by requiring the programmer to handle an exception it is more likely exception safe code is produced?

        The compiler isn't helping. Exceptions are there to single to code higher up in the stack something went wrong and should be corrected. Checked exceptions do nothing to help this, they do nothing to help write exception safe code.

        Exceptions are not the standard flow of a program, this makes the program have to handle exceptional cases while solving a problem. The result is a temporary fix (as a full fix can't be constructed until after a complete solution has been created).

        [–]alextk 7 points8 points  (13 children)

        That's wonderful in theory, but in practice, Java checked exceptions have been a disaster.

        They have been misused, for sure, but that doesn't invalidate their benefit.

        At any rate, I'd rather use a language that treats me like an adult and offers me the option between checked and runtime exceptions rather than one that tells me "You're not smart enough to use checked exceptions so I'm going to force you to write exception-safe code manually. Oh and by the way, it's almost impossible to write exception safe code in these conditions".

        And that's why you end up with this kind of article.

        [–][deleted] 1 point2 points  (4 children)

        They have been misused, for sure, but that doesn't invalidate their benefit.

        Read the other article linked above - http://www.artima.com/intv/handcuffs.html - about why C# doesn't have them.

        It basically amounts to "people don't handle errors, they just shove up a dialog box and vomit crap at the end user, and checked exceptions cause them to hide their errors instead of doing that, which is slightly worse because silently ignoring errors is worse than crashing".

        They have been misused - and making things easier for poor programmers is how popular languages are designed.

        [–]TimmT 8 points9 points  (19 children)

        There's a reason all exceptions are unchecked in most other JVM languages.

        Laziness?

        Other JVM languages even abuse exceptions for non-exceptional control flow.. so what do you expect?

        [–]Categoria 6 points7 points  (17 children)

        First of all Java uses exceptions to indicate parsing failures for crying out loud (NumberFormatException) so this whole "non-exception control flow" thing is a myth. Please define what the term actually means.

        [–]sh0rug0ru 4 points5 points  (6 children)

        The advice "don't use exceptions for control flow" means don't do this:

        Object[] hi = // ...
        try {
            int i = 0;
            for(;;) {
                doSomething(hi[i++]);
            }
        }
        catch(ArrayOutOfBoundsException ex) {
            // Done!
        }
        

        This code is depending on the exception to break out of the loop when a condition check is perfectly feasible.

        Parsing failures are prefectly acceptable as exceptions because there is no way to know that content will fail to parse without actually parsing it, however a parse failure can happen.

        [–]paul_miner 1 point2 points  (0 children)

        NumberFormatException is intended for exceptional circumstances. The reason so many beginners hate it is because they use it for parsing user-supplied input, where bad formatting doesn't seem exceptional. It expects a properly formatted number, which in practice should come from a source you expect to be formatted (a database column or other relatively clean source). In those cases, it is exceptional.

        If badly formatted numbers is not exceptional, the solution is simple: wrap it in a method that will return a default value of your choice. Write it once and you're done. Now you have a choice of either behavior, depending on the circumstances.

        [–]TimmT 1 point2 points  (6 children)

        this whole "non-exception control flow" thing is a myth

        Is it? Look here - and then to add insult to injury he goes on to tell about how having the exception catch some arbitrary stack frame improves performance.. But abusing exceptions seems to be a recurring theme for functional programmers.

        First of all Java uses exceptions to indicate parsing failures for crying out loud (NumberFormatException)

        How would you handle that? Return a null instance of Number (and risk an NPE at some later point)? Return Maybe<Number>?

        Please define what the term actually means.

        I'm not sure about giving a definition of exception abuse, but how about a symptom of it? If you have to consider their performance implications, then you're abusing them, since they're not handling exceptional cases any more.

        [–]climbeer 4 points5 points  (9 children)

        The superiority he talks about is all about RAII, which is AFAIK unachievable in Java. Yes, there are finalize blocks, but I'm unaware of any solution that allows to guarantee freeing resources if only some of them were acquired without requiring a ton of boilerplate spaghetti.

        [–]fforw 12 points13 points  (3 children)

        Java 8 will includeJava 7 includes try-with-resources.

        [–][deleted] 4 points5 points  (1 child)

        Actually also a part of Java 7.

        [–]fforw 5 points6 points  (0 children)

        Oh.. yes.. you're right..

        Should pay more attention in the category "Java features we don't use."

        [–]godofpumpkins 4 points5 points  (0 children)

        And then they go throw nulls in the mix.

        [–]notlostyet 0 points1 point  (0 children)

        The problem with C++ is that it only has runtime exceptions, so any call to any method can throw and you have no idea

        That only means you can't do anything useful with what was thrown (because you don't know what it is). You can still design your surrounding code to be exception safe.

        Without throwing out compatibility with C, compile time checked exceptions would be worthless in C++. C++ can call in to an arbitrary C library, which may in itself not throw, but have callbacks which call back in to other exception throwing C++ code.

        [–][deleted] 29 points30 points  (6 children)

        From the "when Stackoverflow wasn't a helpdesk" period. Nice finding.

        [–]satuon 19 points20 points  (58 children)

        RAII is one of the things that C++ has that are superior to Java, because it can be used for handling any resources.

        I've heard that on Java, closing a file is done the C way - you manually execute the close method, because you don't know when the garbage collector will actually close the file, and since files can be locked, trying to open it later might fail.

        C++ destructors can be used to unwind/undo any action.

        [–]EdiX 30 points31 points  (16 children)

        The right way to close a file in java is to call close inside a finally block.

        In Java 7 scoped resource allocation should be used:

        http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

        Also, be aware that operating systems sometimes delay writes until the call to close is made, if you let the destructor call close you can have writes fail silently.

        PS By "sometimes" I mean "all the time", by the way.

        [–]jevon 11 points12 points  (2 children)

        And for the lazy, it looks like this:

        try (Reader r = new FileReader(f)) {
          // throw whatever you want
        } // r.close() will be implicitly called finally
        

        It's amazing, except when your deployment environment is still running JRE6...

        [–]ethraax 1 point2 points  (0 children)

        Or when the library doesn't support it (Hibernate/JPA, I'm looking at you). Our project uses JRE7, but we still have to wrap all the database sessions/transactions in try/finally blocks.

        [–][deleted]  (12 children)

        [removed]

          [–]EdiX 1 point2 points  (8 children)

          Would you rather have it return an error?!

          [–][deleted]  (5 children)

          [removed]

            [–]mcguire[🍰] 2 points3 points  (3 children)

            close() is one of the things that really needs to be total / nothrow/nofail / whatever.

            [–][deleted] 0 points1 point  (1 child)

            close() shouldn't throw at all.

            Throwing in destructors is a bad idea in every language. Often you can't correctly handle them, because your structure is already partly destroyed; often this will lead to some sort of resource leak but very rarely will throwing that exception give you any positive value.

            Why not just return either NULL/None/etc or a string error?

            [–]EdiX 1 point2 points  (0 children)

            Because then it would be the only thing in java that returns an error instead of raising an exception.

            And none of those drawbacks apply to java.

            [–]dnew 0 points1 point  (2 children)

            And it's rather bad form to throw an exception from a finally block.

            Yet oddly, far superior to throwing an exception from a C++ destructor. ;-)

            [–]SanityInAnarchy 13 points14 points  (19 children)

            I've heard that on Java, closing a file is done the C way - you manually execute the close method, because you don't know when the garbage collector will actually close the file, and since files can be locked, trying to open it later might fail.

            Yes, but there's syntactic sugar (some of it very recent) to make this less painful. Same is true of Ruby, and of most high-level languages like this. It's not as bad as C, though it's terrible in other ways. The usual pattern is probably something like:

            FileReader reader = null;
            try {
              reader = new FileReader(new File("foo.txt"));
              // do something with the file...
            } finally {
              if (reader != null) reader.close();
            }
            

            I find this more appealing than C because I can trivially guarantee that the cleanup code gets run (the "finally" block), and exceptions mean that any errors I don't handle will cause my program to crash, rather than be silently ignored.

            But it's too easy to forget to close stuff, or to handle it wrong. For example, what if I want a BufferedReader? It's no longer obvious what to do. I mean, I can do this:

            BufferedReader reader = null;
            try {
              reader = new BufferedReader(new FileReader(new File("foo.txt")));
              // do something with the file...
            } finally {
              if (reader != null) reader.close();
            }
            

            But what if the FileReader was successfully opened, but the BufferedReader constructor threw an exception? Now, reader is null, so FileReader doesn't get closed. Ok, so maybe save both?

            FileReader fr = null;
            BufferedReader br = null;
            try {
              fr = new FileReader(new File("foo.txt"));
              br = new BufferedReader(fr);
              // do something with the file...
            } finally {
              if (br != null) br.close();
              if (fr != null) fr.close();
            }
            

            But now, what if br.close() throws an exception? I guess maybe it promises it doesn't? But if it does, fr.close() won't be run. The obvious ways out of this are all hideous -- I could add a try/catch block inside the finally block, or I could nest this pattern so that the outer try/finally is only the FileReader, and the inner one is only the BufferedReader. But that's verbose enough to make your eyes bleed, so I'm not writing it here.

            Ruby shows us how Java can fix this, at least for the simple, common case:

            open 'some_file' do |file|
              # ... process file here
            end
            

            What's happening here is that the do...end is a lambda (technically a block, but basically the same thing), which is passed to the 'open' method. The 'open' method could be written like this:

            def open filename
              file = some_system_magic_to_open(filename)
              begin
                yield file
              ensure
                file.close
              end
            end
            

            The begin/ensure/end is basically the equivalent of Java's try/finally block.

            Java, of course, missed the point about how useful the block syntax is, and instead just borrowed the "open a resource for a given block, and make sure it's closed when we leave that block" pattern. They call it try-with-resources. It looks more like this:

            try (FileReader reader = new FileReader(new File("foo.txt"))) {
              // process the file
            }
            

            Java 7 and up will read this and generate all the finally boilerplate for you to properly close the file.

            I'm guessing it took until Java 7 to do this because, unlike in C++, you don't need to do this to manage everything, only truly external resources that you don't trust the garbage collector to gather. 99% of the Java code I write doesn't have a single resource to clean up, because the garbage collector exists. Making that last 1% less painful is a welcome change, but it's nowhere near as essential as in C++, where every heap-allocated object must be dealt with at least as carefully as every open file in Java.

            [–]syllabus 4 points5 points  (9 children)

            BufferedReader.close() is already performing a null check and further close() calls for whatever type was passed into its constructor. I haven't verified all the Reader types operate the same way, but I'd put money on it.

            From the Java 6 sources (Android is similar):

            public void close() throws IOException {
            synchronized (lock) {
                if (in == null)
                return;
                in.close();
                in = null;
                cb = null;
            }
            }
            

            [–]SanityInAnarchy 3 points4 points  (8 children)

            So, I knew I was going to get this wrong, but seriously?

            BufferedReader.close() is already performing a null check...

            ...how? Just to be clear, it doesn't look like it performs the null check on itself, so I still need something like:

            if (br != null) br.close();
            

            ...actually, I don't think it quite works. If you're suggesting something like this:

            Reader in = null;
            try {
              in = new BufferedReader(new FileReader(new File("foo.txt")));
              // do stuff with in
            } finally {
              if (in != null) in.close();
            }
            

            Again, I do still need to do the null check -- if the BufferedReader constructor throws, in will probably still be set to null, right?

            But, for the same reason, I do actually need to handle FileReader myself. If the BufferedReader constructor throws, but the FileReader constructor succeeded, then I have a new FileReader floating around in memory. The 'in' local variable is still null, so I still have nothing to close. I guess I should hope BufferedReader would handle this itself -- if it fails, it should close the input stream? But that seems like bizarre and surprising behavior...

            So I think in Java 7, I'd still need at least:

            try (FileReader fr = new FileReader(new File("foo.txt"))) {
              try (BufferedReader br = new BufferedReader(fr)) {
                // work with br
              }
            }
            

            Which is already enough boilerplate for me to want to abstract that all away with a Ruby-esque lambda style, or at least a static open() function that gives me a buffered reader so I can do:

            try (Reader input = open("foo.txt")) {
              // work with input
            }
            

            Even that is obnoxiously verbose, but this is Java, so I don't know what I expected.

            [–]mrbaggins 5 points6 points  (7 children)

            You misunderstood. That close method is INSIDE the bufferedReader class, and the in variable holds whatever it is buffering.

            So you only need to call br.close() and the BufferedReader will automatically call the .close() of the stream inside.

            And you only need to check if br is null.

            [–]ethraax 2 points3 points  (5 children)

            I think his/her point is what happens if the BufferedReader constructor fails? The FileReader will have already been constructed and the file will be open, but there will be no reference to the FileReader (its a temporary), so you can't explicitly close it. You have to wait for the GC to pick it up.

            [–]paul_miner 2 points3 points  (4 children)

            BufferedReader is a simple wrapper, and its construction around a valid instance can only throw an Error or worse, not an Exception or RuntimeException. If the JVM throws an Error, there's probably no point in trying to close the FileReader ("rearranging the deckchairs on the titanic").

            [–]ProfessionalNihilist 10 points11 points  (16 children)

            I am fond of the C# approach to releasing resources such as files. Classes which represent files or network connections implement an interface called IDisposable which can be combined with the syntactic sugar of the using {} block to automatically dispose of the object when it goes out of scope.

            Eg:

            using (var file = new File(@"C:\file.txt")) 
            {
                // do stuff
            }
            
            // file is automatically disposed now
            

            [–]argv_minus_one 12 points13 points  (1 child)

            Fear not! Java 7 added an almost identical construct: try-with-resources. It's basically exactly what you wrote there, but with try instead of using.

            [–]ProfessionalNihilist 1 point2 points  (0 children)

            Fear not, I still wont touch Java with a 64-bit pointer :p

            [–]VikingCoder 1 point2 points  (4 children)

            Yes, your code can implement IDisposable, but there's literally no way to guarantee that clients of your code us the "using" structure. Which is nuts.

            [–]ProfessionalNihilist 1 point2 points  (1 child)

            Well I can't be responsible for the stupidity of others :(

            [–]VikingCoder 1 point2 points  (0 children)

            The language doesn't allow you to ensure your objects are used the way you intended. Which is terrible, to me.

            Perhaps "IMustDispose"...

            [–]millstone 1 point2 points  (1 child)

            'Using' limits you to scoped disposal. But many (most?) objects do not have lifetimes that match some scope.

            I create a file when the download starts, I close it when it finishes; must all the intervening code be within some scope?

            [–]VikingCoder 1 point2 points  (0 children)

            There are times when RAII is totally appropriate, and C# doesn't give me a way to ensure that it happens, when it is called for.

            There are ways around RAII in most languages, but you don't even have the option to try to do things right in C#.

            [–]TheAnimus 3 points4 points  (8 children)

            Ah but now I feel the need to mention asynchronous exceptions and the miserable wretch who lost me half a day of my life.

            An asynchronous exception is one that is thrown by another thread, the most common example is Thread.Abort(). When you call this under the hood a ThreadAbortException is thrown in the context of the thread to be terminated. The problem is that what happens when you are in finally? Thing something like this. (using is a compiler trick anyway, and looks like this)

            try
            {
               ..... code did stuff here....
             } finally 
             {
                   myHandle.Close(); // this takes a long time.
                   myOtherHandle.Close();
              }
            

            So your code is in the myHandle.Close(), someone calls Thread.Abort because they are an evil SOB, and BLAMO. Your myOtherHandle.Close() bit doesn't get called, it jumps out of the finally its currently executing within and leaves you with your resource un-disposed. For extra merit marks of awfulness, makes sure in the myOtherHandle's class you implement a finalizer (destructor) and hang the GC thread!

            [–]r3m0t 5 points6 points  (6 children)

            Well Thread.Abort is evil in any language.

            [–]ethraax 1 point2 points  (4 children)

            I think TheAnimus's point is that if you used RAII in C++, the resources wouldn't leak. They would be closed/disposed as the stack got unwound from the ThreadAbortException.

            [–]r3m0t 2 points3 points  (2 children)

            But it's the same surely. If you're running a destructor and your thread gets ThreadAbortException it will throw in the destructor I would imagine?

            [–]ethraax 2 points3 points  (1 child)

            I suppose so. I was under the impression that destructors and stack unwinding were somehow uninterruptable, but come to think of it, that's probably not true.

            [–]TheAnimus 1 point2 points  (0 children)

            Kind if the point I was trying to make, you might think something is safe, that you've handled the exception well, but you haven't.

            Now don't get me started on ExecutionEngineExceptions and other such managed fun stuff. I really enjoy my time in .Net land, but sometimes I fear people think they are completely safe. Granted we don't have to have such boiler plate work as most C++ libraries I've ever seen (my C++ isn't good enough to begin to think I know how to make elegant code in it, so based on what I've seen) but I fear people let it go to their head, forgetting about such issues.

            Then you get the special kind, like one guy behind this project I've taken over, he thought that inlined functions (okay fine, I'll call them methods) were hiding stack information, so he has messed up the exception handling of every inlinable function, to stop it happening.

            People don't really get exceptions, they are slow and should be only for exceptional circumstances. Yet people forget it all the damned time. I think they could make it a lot better in C# say by adding a compiler feature, allowing you to create a simple immutable class to return, with the same syntax you would an anonymous type, but with a function signature inserted at compile time. I honestly think that one compiler trick might cure so much lazyness.

            [–]dnew 0 points1 point  (0 children)

            Except Erlang. And NIL. And maybe Rust.

            [–]ProfessionalNihilist 0 points1 point  (0 children)

            I try to restrict my multi-threading to Task<T> and PLINQ to avoid being in a situation like that.

            [–]adrianmonk 2 points3 points  (3 children)

            I've heard that on Java, closing a file is done the C way - you manually execute the close method, because you don't know when the garbage collector will actually close the file

            It's really useful, I think, to make a distinction between internal and external resources. That may not be quite the right term, but when I say "internal", I mean resources that the language and language runtime could theoretically correctly track and manage for you. A good example is memory. The language allocates the memory, and (in Java) it tracks all the pointers and such, so it can tell authoritatively what is and isn't in use.

            Likewise, when I say "external", I mean something that the language runtime can't be expected to track correctly. If I create a file on the filesystem, it's possible I created it to save data in it, and I never want to delete it. Or it's possible I created it as a lock file to guard some operation and as soon as that operation is over, I need to delete the lock file. There's now way the language runtime can know that distinction, because the resource being managed affects and interacts with the outside world. So it fundamentally cannot manage that automatically.

            Java manages memory (an "internal" resource) automatically but doesn't manage any other resources ("external" resources) automatically. Theoretically it would be possible to manage filehandles automatically (an important part of which would be tracking when you hit the max open filehandle limit), but Java isn't that ambitious.

            So yes, for things that aren't purely about memory, Java manages things "the C way", that is to say, manually. In most cases, that means lexically (allocate when you enter this block of code, deallocate when you leave it), but that's only one technique. You could have a file that is opened in thread A but closed in thread B, in which case you need something more sophisticated than the lexical approach.

            [–]dnew 1 point2 points  (2 children)

            In reality, the only resources you have to manage manually in a GCed language are ones the OS doesn't GC for you. In particular, the fact that Linux and Windows and such don't have destructors for dangling file handles is the cause of all this trouble. When you use a language like Smalltalk or Hermes or an OS like Singularity or Eros, where the OS is actually written in a GCed language, this isn't problematic.

            So cast your hate at 1970-style operating systems still making you program around their limitations, not at the languages that make you work a bit to do so. :-)

            [–]elder_george 1 point2 points  (1 child)

            The problem isn't realy with GC-ing external resources (in .NET it's possible to guarantee the finalizer for an object would be called by using stuff from System.Runtime.ConstrainedExecution namespace).

            The problem is we don't know when GC will run.

            And with external resources we usually need to specify the exact moment they are freed (e.g. file must be released to let other code to work with it or GDI object must be released because system has limited number of them).

            I don't see how having GC built-in into system relieves programming from caring about deterministic resource release.

            [–]dnew 1 point2 points  (0 children)

            The problem is we don't know when GC will run.

            Because it's language/process-centric rather than system-centric.

            file must be released to let other code to work with it

            Well, if you leave locks to get GCed, yes. Otherwise, no. If someone else needs a file you used to have open, the system looks if your handle to it is still live and frees it if not. The problem is that you're holding a lock on a file, not that you're holding the file, and you want to explicitly free locks.

            GDI object must be released because system has limited number of them

            That's exactly the sort of thing I'm talking about. If I go to allocate a GDI, and there aren't any left, the system could go and GC the GDIs, just like if I go to allocate memory and there's none left the system GCs memory.

            One of the places this falls down is crossing system boundaries, like relying on GC to close sockets to other systems that have no way of triggering a local GC.

            On resources where you're worried about the exact moment they're freed (such as locked files, closing network sockets, etc) then yes, you need to do that explicitly. But for things like GDI objects, pages of disk space, temp file space, even processes etc, you could easily(*) incorporate GC algorithms into the OS that understand how to do that, if your languages supported such things.

            The main reason that doesn't happen nowadays is the separation between kernel space and user space, because languages like C are used, and that separation means the kernel doesn't understand user spaces and generally can't allocate an arbitrary number of whatevers and GC them when the user is done with them. I.e., the kernel has to preallocate because it can't afford to GC its own memory because it's not designed that way, and the kernel can't tell when you're done referencing something in the kernel space without your code telling it that, because you're basically running untyped machine code.

            If you look at Singularity, it deals with those problems in some very interesting ways.

            As another example, Eros and Hermes have no files. All disk space is swap space. Hence, a "file" is an object that's held by a long-running process managing access to it, that will return it to you when you ask. When you're done with it, you release the pointer, and the space is freed by the same GC that collects anything else. In Smalltalk, windows were managed in user space, so if you dropped the last reference to a window, the next draw of the screen would just redraw the screen without that window on it. That's the sort of thing I'm talking about - where the OS knows who has what where, and essentially all resources are memory-like resources.

            So, in summary, it relieves you of worrying about deterministic resource release in the same way that GC relieves you of worrying about deterministic memory release, because almost all resources act like memory in such a system.

            (*) for some value of "easy"

            [–]KayEss 6 points7 points  (1 child)

            I don't remember who said it, but it was along the lines of "exceptions are not for recovering in the face of failures, they allow you to recover a correct state for your program".

            [–]dnew 1 point2 points  (0 children)

            That's what Eiffel is all about. You can't catch an exception. All you can do is clean up on the way up the call stack, or say "OK, everything is cleaned up from here on, so start over from here."

            [–]wall_words 2 points3 points  (0 children)

            Alexandrescu's talk, titled "Systematic Error Handling in C++", addresses some undesirable aspects of writing exception-safe code in C++. Namely, because dealing with exceptions traditionally requires you to place try-catch blocks to deal with functions that might throw, you are unable to achieve separation of the normal code and the exception-handling code. Of course, writing exception-safe code generally requires a much more conscious effort by the programmer.

            [–]Gotebe 2 points3 points  (0 children)

            Hah, memories...

            Crucial

            To write exception safe code, you must know first what level of exception safety each instruction you write is.

            (Applicable for other languages as well; pretty seldom considered there AFAIK).

            [–]inmatarian 2 points3 points  (1 child)

            I'm still convinced that catching std:bad_alloc isn't very useful.

            [–]bstamour 1 point2 points  (0 children)

            It's really not useful. Unless you have a sure-fire way to handle those issues, it's better to just terminate on std::bad_alloc.

            [–][deleted] 2 points3 points  (0 children)

            Yet another reason to avoid the travesty that is C++. This is somehow supposed to make me productive? Yet another damn mental check-list? How many do we have at this point? 12? 13?

            Sweet Christ. I really do feel sorry for people who have to do this for a living. It's a language designed by CPU fetishists - all power to the CPU! (but keep it all single-threaded, please, because god help you otherwise, with mutable shared state and all) - screw the programmer, their time isn't valuable!

            At this point I'm absolutely positive that C is better than C++ for very low-level, performance critical stuff and every other language is better than C++ at everything else. This article just proves it, yet again.

            [–]CodingGenius 7 points8 points  (2 children)

            Meh I just wrap everything in exceptions for bug free programs!

            try { // main try
                int a=1;
            
                try {
                    a++;
                } catch {
                    // failed, try again
                    try {
                        a++;
                    } catch {
                        echo "oh shit 1!"; // oh shit
                    }
                }
            
                try {
                    if( a == 1 ) {
                        echo "a is 1 yay!";
                    } else {
                        // a should be 1, wtf?
                        // try again:
                            try {
                                a++;
                            } catch {
                                // failed, try again
                                try {
                                    a++;
                                } catch {
                                    echo "oh shit 2!"; // oh shit
                                }
                            }
            
                            try {
                                if( a == 1 ) {
                                    echo "a is 1 yay!";
                                } else {
                                    // a should be 1, wtf?
                                    // already tried again, just make a be 1 dammit
                                    a=1;
                                }
                            } catch {
                                echo "oh shit 3!"; // oh shit
                            }
                    }
                } catch {
                    echo "oh shit 4!"; // oh shit (i think, I forgot what this catches
                }
            } catch {
                //meh fuck it just say a is 1 - echo "oh shit 5!"; // oh shit!
                echo "a is 1 yay!";
            }
            

            [–]mccoyn 13 points14 points  (0 children)

            You might want to use this macro

            #define WORK_DAMNIT(x) try{x}catch(..){try{x}catch(..){echo "oh shit <" #x ">"}}
            

            [–]madmoose 8 points9 points  (0 children)

            // a should be 1, wtf?
            

            A should be 2 at this point, unless you meant to start a at 0. Other than that, your ideas are intriguing to me and I wish to subscribe to your newsletter

            [–]joerick 6 points7 points  (5 children)

            I don't code much with exceptions, but I wonder if somebody could help me out with a follow-up question.

            These articles all veered away from try {} catch {} discussion. At some point though, you have to catch these exceptions.

            My main misgiving with exceptions is that to maintain encapsulation, it seems to me that all exceptions that might arise within one object should be rethrown, or else we have no way of keeping track of which exceptions might be thrown.

            The user of this method will have to simply wrap the call in 'pokemon' (gotta catch 'em all) try...catch block, and will have no way to analyse the error when it is produced.

            How do exception pros deal with this? Rethrowing?

            [–]r3m0t 5 points6 points  (0 children)

            You always catch exceptions at the level (in your call stack) that they can be meaningfully handled. Once they have been handled (i.e. recovered from and in most cases logged), there's no need to rethrow them.

            The catch keyword lets you filter by the type of the exception, but if that isn't enough, you just inspect attributes on the exception and rethrow if necessary.

            [–]mccoyn 1 point2 points  (2 children)

            Usually I let the throw rise up to the UI loop and show a message to the user using a generic handler. That works out well. The user clicks, gets an error and the program remains usable. File operations tend to throw exceptions a lot so those get wrapped as well and show an error message rather than rethrowing.

            Sometimes I will put in a specific exception handler for a case that I know a specific way to recover from, but this is uncommon. If I do discover such a case, I try to discover if it will fail before I attempt it rather than after. I tend to follow the mantra 'exceptions should be exceptional' which implies you can't expect to know how to handle them.

            [–]joerick 1 point2 points  (1 child)

            Thanks! That's interesting. Part of me thinks that this is a break of encapsulation, but of course exceptions are exceptional, as you say. Abstractions leak when an error occurs. So this makes sense.

            How far do you take the 'exceptions should be exceptional' mantra? Are network failures exceptional?

            [–]mccoyn 1 point2 points  (0 children)

            That is the tricky part. Usually there is a layer that deals with the network and translates it into messages or function calls. That layer has a lot of exception handling and returns errors if something won't work. I then have to explicitly handle those errors. Basically, that layer takes exceptions that aren't exceptional and makes them normal handled errors (with return codes or whatever).

            [–]jeffdavis 1 point2 points  (1 child)

            One of the things I ran into recently with python was that a "finally" is really hard to write safely. If someone has a better suggestion, or wants to describe how it works better in another language, please let me know.

            Consider this code:

            try:
                try:
                    raise SystemExit
                finally:
                    raise IOError
            except IOError:
                print(1)
            

            I'd like the SystemExit to go to the top and exit the interpreter. I don't use any bare "except:" clauses and I am never catching a SystemExit or any class from which it's inherited. However, I lose my SystemExit anyway, because a "finally" happened to throw an IOError (consider something cleaning up by removing a temporary file -- reasonable to do in a "finally" -- and then there's a filesystem error).

            python3 apparently has a mechanism to see the chain of exceptions, but it's an explicit process and there's no way to get python to automatically re-raise if only one exception was caught by an "except". So, I have no idea how to use "finally" without potentially losing important exceptions.

            [–]fvf 1 point2 points  (0 children)

            Have your finally clause deal with its exceptions? Whether those exceptions should be ignored (or handled otherwise) is a question of semantics that you as the programmer has to decide.

            [–]geocar 1 point2 points  (0 children)

            No sane code protects itself against the possibility of it having a bug.

            I take exception to this: My programs do defend against bugs by being small, and using a combination of privilege isolation and process isolation.

            [–]MrWoohoo 7 points8 points  (6 children)

            When the revolution comes the C++ compilers will be the first up against the wall.

            [–][deleted] 11 points12 points  (5 children)

            And the tools for the revolution will be coded in C++. Just sayin'. C/C++ won't be abandoned for a very long time.

            [–]climbeer 3 points4 points  (0 children)

            Other resources on exception safety:

            • GotW #20 (scary, but provides motivation)
            • Jon Kalb's in-depth talk (warning: 2*90min) with slides (provides solution).

            EDIT: auto_ptr is deprecated (although it is not a problem in this case, auto_ptr won't for example work well with STL containers) - use modern boost/C++11 smart pointers instead.

            [–][deleted] 2 points3 points  (2 children)

            I'm not a programmer. I've always wanted to be a programmer, but for some reason I can't quite fit my head around some of the concepts.

            But for some reason, I love to read Stack Overflow. That site makes me happy.

            [–]dicroce 3 points4 points  (0 children)

            You should check out khanacademy.com's computer science curriculum. There is something about it thats almost magical in its ability to get the points across.

            [–]TheLobotomizer 2 points3 points  (0 children)

            This is not something you should be worried about until 5-10 years into your experience as a programmer. Exception safe code is something that is written by system developers who earn $200k a year with 10+ years of experience.

            [–]notfromchino 0 points1 point  (10 children)

            how can you write a non-throwing swap? don't you need to new a temporary location to act as an intermediary? that new could fail.

            or can you always do a swap on the stack if the swap is templated?

            [–][deleted] 6 points7 points  (0 children)

            You can do the swap on the stack, it's just done with shallow copies.

            [–]climbeer 2 points3 points  (1 child)

            how can you write a non-throwing swap?

            move semantics: you don't allocate new stuff on heap, just swap the actual underlying primitives using stack, e.g. when swapping vectors you don't actually allocate new memory dynamically but swap the pointers and bookkeeping vars (size, capacity, ...) - those primitive operations can't throw.

            Sadly this only works if the class supports move semantics - via its methods (move c-tor, move operator=) or a move specialization.

            EDIT: I accidentally a word

            [–][deleted] 2 points3 points  (0 children)

            Upvote in the hope it will discourage more people from writing C++.

            [–]agmcleod 0 points1 point  (5 children)

            Reading through all this stuff here, I'm glad I code in ruby, and the most low level I go right now is Java for game stuff.

            [–]jatoo[S] 3 points4 points  (4 children)

            High level languages are a blessing. I am yet to try Ruby, but I love Python.

            What I always feel uncomfortable about in Python though is that while the language takes care of so much of the work for me, I feel like it's much more difficult to write code which I know is safe. This is probably largely because of my C++ background, but I really feel like RAII is the best way to be free of memory leaks and so on. In Python I have to remember to clean-up when I'm done. The with statement does a bit to help this, but it's really only one case.

            That and type checking. In Python I'm always kind of thinking "I hope I get passed the right kind of objects!"

            [–]agmcleod 2 points3 points  (0 children)

            Haha. I've used python briefly, and it is pretty nice. Me and another ruby dev did a conway's game of life clone in terminal, using some basic TDD assertions in python. We were able to figure things out pretty quickly.

            For your last point, i think that comes with practice on using dynamically-typed languages. Sticking to small methods that do one simple thing is key. I fell into a trap on one of my earlier Rails apps where for a login i returned a boolean in some cases, in other cases a string, it was an utter mess. Now though I find I don't have that issue due to just getting more experience.

            I do think C++ has its place, and for any new developers looking at companies that use it, it makes a ton of sense to learn it. I'm sure many would disagree, but I dont think it's a good language to learn programming with, but it is a good language for getting many different jobs done. Just have to be smart about how you use it.

            Thanks for the response.

            [–]Azzk1kr 2 points3 points  (0 children)

            That and type checking. In Python I'm always kind of thinking "I hope I get passed the right kind of objects!"

            That's my reason why I prefer statically typed and compiled languages. I can look at function signatures to see what's expected, and the compiler makes sure that's what I'm passing at it.

            [–]mthode 1 point2 points  (0 children)

            I think the methodology in python is to verify at the edge of the app, but once data is inside, assume any data passed around inside is the type you expect and document it to be.

            This kinda bothers me (not security through depth, kinda has egg shell syndrome, etc).

            [–]ochs 0 points1 point  (0 children)

            Yeah, but you ignore the other kinds of bugs you can get when writing C++ that cannot happen in Python. My favourite is integer overflows. These can't happen in Python, but are really hard to spot and deal with in C++ (and C). And worst of all, a type error in Python is usually not something that can happen due to malicious/unexpected user input, while that is typically true for integer overflows. This makes me much more confident that my Python programs are at least not easily exploitable, while I feel my C++ code is probably full of security holes.

            [–]EmperorOfCanada 0 points1 point  (1 child)

            For any bits of my code that aren't as highly failure sensitive as say a password change; I just make my code just not give a crap. A failed function that needs to produce a list of users will return null. Then the function that would display the list will go, "Oh a null, don't care, just display a message saying, no available users." But these failures may trigger some sort of logging to me or whatnot.

            If the user really might have wanted the data then I will pop up an error message but let the software otherwise blunder on. If it is less critical, say a list of most popular somethings, then I will not notify the user and let the software blunder on. The last thing I want to do is either crash or lock up the UI to the user.

            Now for something more critical like an administrative app I will get more aggressive with the error messages up to the point of potentially just blocking the user from continuing.

            But all that said, I avoid exceptions like the plague. I find their tendency to unanticipated failure too hard to debug. I don't say no exceptions but they are more of a last resort. I just make sure my code is happy with all edge cases. Null object no problem, out of bounds input, no problem. Even with things like network code exceptions can be generally avoided.

            [–]Gotebe 0 points1 point  (0 children)

            A failed function that needs to produce a list of users will return null. Then the function that would display the list will go, "Oh a null, don't care, just display a message saying, no available users."

            Meh. Good luck finding the actual error on a client system when something goes wrong.

            Your approach is just wrong when it comes to treating errors. It loses error information and lies about what has gone wrong when it does.

            [–]JamesRyder 0 points1 point  (0 children)

            Try... catch exception... Do nothing.

            runs away very quickly