4 ms·
This could not have happened with C++ exceptions and RAII instead of manual error checking and goto for cleanup ;)
by nikbackm 13y ago
This could not have happened with C++ exceptions and RAII instead of manual error checking and goto for cleanup ;)
- eliasmacpherson 13y agoIt could actually. Exceptions and RAII are not resilient against typos and programmer error. If the exception handler caught the wrong type, for example catching by value instead of reference, instead of having a catch(...) it would have the same problem as the above. It's harder to spot this sort of error than a double goto and incorrect parentheses - because you have to check the code that throws and the code that catches. Admittedly in the scenario I lay out - what happens is an error is thrown and not caught, rather than a check being skipped, but the net effect is equivalent - and it takes 1 character out of place to invoke.
- nikbackm 13y agoI don't see the possibility for catching the wrong type (or not catching it) if you get one character wrong. Unless of course you have two valid type names that just differ in one character, but that is a general pitfall and not exception specific. If you always throw by value (and not by pointer) then it does not matter if you catch by value or by reference, the catch block will be activated either way. The only issue is possible slicing if you throw a derived instance and catch a base class type. You might lose error information that way, but the program will not crash due to an uncaught exception.
- eliasmacpherson 13y agoOk for example: int e; int update() { throw &e; } the & is the one character - it's a typo - only catch(...) will catch it.
- nikbackm 13y agoWell, since you're throwing an int-pointer then catch(int*) should also catch it quite happily. I guess you mean there will only be a catch(int) in addition to catch(...) so in that aspect you're right of course. Still, I would think taking the address of something you throw should ring quite a few warning bells as opposed to merely a missing ref (&) in the catch handler. Similarly to "return &e" which would also be suspicious and require an extra look or two.
- eliasmacpherson 13y agoMy point being it would raise far less warning bells than an unguarded goto.
- pjmlp 13y agoSadly it could, because of the C compatibility you can never be sure if a developer wouldn't write something like this. The same applies to any other language that allows for copy-paste of C code.
- laureny 13y agoAny language that lets you omit braces for single statements is prone to this bug, which includes C++.
- hub_ 13y agoSuggestion to clang and gcc developer: implement -Wmandatory-curly-braces At least, short of making it mandatory it would at least signal bad style.
- nikbackm 13y agoWell it was mostly a tongue-in-cheek comment (was thinking of yesterday's C++ exception topic), but essentially true as you would not have used the "if + goto" with C++ error handling. Of course you can write the same bug (and more) in C++ too.
- kabdib 13y agoNo, you're worse off in C++, where the semantics of exceptions (especially in the area of resource allocation and deletion) are complex and hard to reason about. I've done a bunch of kernel and other systems work in C and in C++, and my experience is that the C is a lot clearer. This type of code is all about not having magic side effects; everything needs to be in the open and very plain, or bugs start to get pretty subtle and hairy. I'm not saying "Don't do systems programming in C++", because clearly you can. But it takes discipline to succeed, probably more discipline than you need to apply than if you're writing C.
- thrownaway2424 13y agoI don't know about exceptions (they are forbidden where I work) but any amount of C++ would significantly improve this implementation. There is code all over this library that allocates and deletes buffers in structs passed in as function arguments, i.e. other code's structs that nobody should be dicking around with except through constructors, destructors, and accessors. This code would also be about half as long in straight-forward C++.