• Marc (unregistered)

    If I had money every time I've seen:

    <snip>} catch(Exception ex) { throw ex; } finally { }

    It makes me want to get out a roll of coins and beat them! And then having to explain that not only did they do nothing useful, but they threw away the exception stack too! (by using "throw ex" instead of "throw").

    (Minor: "In Java and C++"; should read "and C#"?)

  • Bobby Knight (unregistered)

    My guess (which doesn't reduce the WTF-ness) is that they were coming from old VB and were fans of "ON ERROR NEXT". Exceptions confused them. They discovered (probably by accident) that using a try block, and then doing nothing with it, would keep the program trucking without "messing anything up"...recreating their beloved "ON ERROR NEXT"

  • Cj (unregistered)

    It almost appears as if they were running code that they needed to be sure that would be broken out of if anything failed, but it didn't exactly matter if the code failed in the first place.

  • RadarRider (unregistered)

    As noted earlier, that structure allows the code to continue in the face of any exception encountered in the try block. In other words, this may encounter an exception but I don't care; keep going.

    What's interesting is that I've actually seen that technique in at least one C# programming book.

  • red potato (unregistered)

    Finally the error messages go away. It's debugging as in "stop bugging me with error messages".

  • Derrick Pallas (cs) in reply to Cj
    Cj:
    It almost appears as if they were running code that they needed to be sure that would be broken out of if anything failed, but it didn't exactly matter if the code failed in the first place.

    Broken out of what?

    red potato:
    As noted earlier, that structure allows the code to continue in the face of any exception encountered in the try block. In other words, this may encounter an exception but I don't care; keep going.

    Continue where?

    Uncaught exceptions bubble up the call stack. The only reason this programmer used finally was to keep the compiler from complaining. try blocks are invalid unless they have a finally statement or at least one catch statement. Since no catch was provided, finally was added to a useless try in order to trick the code into building.

    I assume this was copy-and-paste-and-cut gone wrong.

  • Simon Bradley (unregistered)
    felix:
    Anyway, a try clause whitout a catch might as well be absent, right?

    Wrong. For example:

    try
    {
        throw new Exception();
    }
    finally
    {
        print("Hello, Mummy!");
    }

    To all the people who claimed that try/finally suppresses exceptions: no, it doesn't; it just allows you to do something before the exception propagates out. For example, my example prints "Hello, Mummy!" - and then throws.

  • Pon (unregistered) in reply to RadarRider
    RadarRider:
    As noted earlier, that structure allows the code to continue in the face of any exception encountered in the try block. In other words, this may encounter an exception but I don't care; keep going.

    What's interesting is that I've actually seen that technique in at least one C# programming book.

    No, that doesn't happen without a catch cause. Try-finally is used when you MUST clean up a resource reguardless of wether or not an exception is throw. The 'using' keyword turns into a simple try{whatever code in here}finally{createdResource.Dispose();}.

  • red potato (unregistered) in reply to Derrick Pallas

    Uh, is the quoting system here working correctly? That no me werdz.

    Anyway, proposing the introduction of the try{}ignore{} clause.

  • Simple Life (unregistered) in reply to red potato

    This WTF is really useful to see how many people that think they understand Exceptions and like to look at other peoples bad code, probably write some pretty poor error trapped code themselves!

  • Alex (unregistered)

    I dont think the author of this piece knows much about programming in Java, still he seems to be quite happy to demonstrate his ignorance in public.

  • Jon Skeet (unregistered) in reply to Alex
    Alex:
    I dont think the author of this piece knows much about programming in Java, still he seems to be quite happy to demonstrate his ignorance in public.

    Which piece of ignorance about Java? There's a typo where C++ should be C#, but the description of Java seems right to me. Admittedly there are finalizers, but they're not the same as C++ destructors as they're non-deterministic.

    What I would like to point out is that finally can be used for more than resource release - there are times when it would be very useful to have in C++, too...

    Jon

  • craiga (cs)

    You see this sort of thing when somebody comes from a VB or VBA background. It's just "on error resume next" for the Java (or C#) generation.

  • Guran (unregistered)

    Hmm finally is indeed very useful....used right. While the author is correct, saying most resources clean up themselves in .NET, there are always situations where you must ensure resources are shut down correctly. (Correctly as in "As I want, not according to some default rule.) File operations anyone? Database transactions?

  • aquanight (cs) in reply to red potato
    red potato:
    Anyway, proposing the introduction of the try{}ignore{} clause.

    That already exists, but it's a WTFy thing to do: exceptions shouldn't ever be silently dropped unless you have a DAMN good reason to (ie: the "will never happen under expected run conditions (pre-validated inputs, etc) but compiler makes me try-catch anyway" exceptions).

    Especially in java, it is downright wrong to ignore some particular throwables: namely Error and subclasses. In fact, anyone who catches Throwable, Error, or a subclass should have his hands cut off. Catching Exception might be reasonable ("but you lose the exception type" - runtime type never goes away and if the exception was wrapped for rethrow (as it should be, to not f*k up the stack trace stored within) could be retrieved via instanceof, .getClass(), etc). Error? Please no. I want to actually KNOW if a java program needs more memory, etc, thank you very much.

    Derrick Pallas:
    The reason C++ doesn't have this block is because it's unnecessary: since acquisition is initialization, most resources are local.

    IMHO C++ does need a finally thanks to the new/delete operators. Oh sure, Java/C# have finally but pretty much everything accessed by java/c# code is automatically managed - unmanaged resources are wrapped in managed objects that make sure dispose/close gets called from the destructor when user code forgets to. C++ does not have that luxury - last pointer goes away and whatever resource it pointed to is never to be reclaimed, closed, or otherwise until exit() (at best) or reboot (at worst) or use some refcounted pointer-wrapper class to prevent those. So, yes, I really think C++ should've had a finally {} before java/.NET did.

    You might wonder why one is allocating on the heap an object that might well only be used locally. The heap is generally several times larger than the stack, so there's nowhere better for obsenely large structures. Nevertheless, it's a pain the ass to remember a bunch of deletes before every exit point from the function(*) (every throw, return, etc, and one must exclude the object being thrown/returned). A try/finally would simplify that greatly.

    (edit: (*) = one could extend this to other locally scoped variables, eg loop vars would need deletes before a break as well, etc)

  • john (unregistered)

    the thing that disturbs me the most is that the coder didn´t use a "big" try, finally block but made many of them.

    He wants to ignore every exception anyway so what´s the point in making a try, finally around every single method that could through an exception?

  • Alex (unregistered) in reply to Jon Skeet
    Jon Skeet:
    Alex:
    I dont think the author of this piece knows much about programming in Java, still he seems to be quite happy to demonstrate his ignorance in public.

    Which piece of ignorance about Java? There's a typo where C++ should be C#, but the description of Java seems right to me. Admittedly there are finalizers, but they're not the same as C++ destructors as they're non-deterministic.

    What I would like to point out is that finally can be used for more than resource release - there are times when it would be very useful to have in C++, too...

    Jon

    "finally" in Java is used not only to free local resources. In fact it is a proper way to free any kind of resources.

  • Jon Skeet (unregistered) in reply to Alex
    <snip>
    Alex:
    "finally" in Java is used _not only_ to free _local_ resources. In fact it is a proper way to free any kind of resources.

    I don't think there was a very strong implication that the author only considered local resources worth freeing. Yes, as others have pointed out it would be good to have finally blocks in C++ for various reasons, but I don't think it was reasonable to draw the conclusion that the OP doesn't know much about programming in Java.

  • Alan (unregistered) in reply to aquanight
    IMHO C++ does need a finally thanks to the new/delete operators. Oh sure, Java/C# have finally but pretty much everything accessed by java/c# code is automatically managed - unmanaged resources are wrapped in managed objects that make sure dispose/close gets called from the destructor when user code forgets to. C++ does not have that luxury - last pointer goes away and whatever resource it pointed to is never to be reclaimed, closed, or otherwise until exit() (at best) or reboot (at worst) or use some refcounted pointer-wrapper class to prevent those. So, yes, I really think C++ should've had a finally {} before java/.NET did.

    This is wrong. Look up RAII (Resource Acquisition Is Initialization). In idiomatic C++, you don't use "new" (or any other resource acquiring operation) anywhere other than a constructor (or the parameter to a constructor), and you don't use delete (or any other resource releasing operation) anywhere other than a destructor.

    So, for example, to safely use new/delete without finally:

    #include <memory>
    void some_function()
    {
      std::auto_ptr<BigObject> pobj(new BigObject()) ;
      // Use your object.  You don't need to worry about deleting,
      // or even a try/catch block.  No matter what happens delete
      // will be called correctly when you leave the function.
    }
    
  • W (unregistered) in reply to aquanight
    aquanight:
    Catching Exception might be reasonable ("but you lose the exception type" - runtime type never goes away and if the exception was wrapped for rethrow (as it should be, to not f*k up the stack trace stored within) could be retrieved via instanceof, .getClass(), etc).
    If you don't like compile-time type checking, code in PHP. Catching Exception, then checking the runtime type? I've submitted code like that as a wtf before...
  • Paul (unregistered)

    You might find that the reasoning behind using Finally was because it came from Delphi.

    Yes it is present in Java, but one of the lead designers for C# (rumour has it) was also one of the lead designers for Delphi which implements that.

    Normally it's in the form of

    try except on E : exception do begin // if your handling needs more than one line end finally end

    And it's been there since the early versions of Delphi that I can remember.

    However the real WTF is why he isn't using a catch. try finally with no catch will just raise the first exception it hits and then stop the procedure / function.

    Do you think he thought that the finally would keep it running so it tried all the options?

  • noname (unregistered) in reply to aquanight
    aquanight:
    red potato:
    Anyway, proposing the introduction of the try{}ignore{} clause.

    That already exists, but it's a WTFy thing to do: exceptions shouldn't ever be silently dropped unless you have a DAMN good reason to (ie: the "will never happen under expected run conditions (pre-validated inputs, etc) but compiler makes me try-catch anyway" exceptions).

    Especially in java, it is downright wrong to ignore some particular throwables: namely Error and subclasses. In fact, anyone who catches Throwable, Error, or a subclass should have his hands cut off. Catching Exception might be reasonable ("but you lose the exception type" - runtime type never goes away and if the exception was wrapped for rethrow (as it should be, to not f*k up the stack trace stored within) could be retrieved via instanceof, .getClass(), etc). Error? Please no. I want to actually KNOW if a java program needs more memory, etc, thank you very much.

    Derrick Pallas:
    The reason C++ doesn't have this block is because it's unnecessary: since acquisition is initialization, most resources are local.

    IMHO C++ does need a finally thanks to the new/delete operators. Oh sure, Java/C# have finally but pretty much everything accessed by java/c# code is automatically managed - unmanaged resources are wrapped in managed objects that make sure dispose/close gets called from the destructor when user code forgets to. C++ does not have that luxury - last pointer goes away and whatever resource it pointed to is never to be reclaimed, closed, or otherwise until exit() (at best) or reboot (at worst) or use some refcounted pointer-wrapper class to prevent those. So, yes, I really think C++ should've had a finally {} before java/.NET did.

    You might wonder why one is allocating on the heap an object that might well only be used locally. The heap is generally several times larger than the stack, so there's nowhere better for obsenely large structures. Nevertheless, it's a pain the ass to remember a bunch of deletes before every exit point from the function(*) (every throw, return, etc, and one must exclude the object being thrown/returned). A try/finally would simplify that greatly.

    (edit: (*) = one could extend this to other locally scoped variables, eg loop vars would need deletes before a break as well, etc)

    Usually in C++ resources (including memory) are managed by a class. The classes' destructors are responsible for cleanup. For simple "local" heap objects created with new you can always use the auto_ptr class.

    While I'm not willing to say there would never be a need for finally, I've never really encountered one.

  • XIU (cs) in reply to john
    john:
    the thing that disturbs me the most is that the coder didn´t use a "big" try, finally block but made many of them.

    He wants to ignore every exception anyway so what´s the point in making a try, finally around every single method that could through an exception?

    He isn't ignoring them :) Finally doesn't ignore the exception, it allows you to first do some other code before throwing the exception. So the whole try with empty finally does NOTHING!

  • woohoo (unregistered) in reply to Marc
    Marc:
    It makes me want to get out a roll of coins
    we always new that's what it was.
  • nn (unregistered)
    In Java and C++, no such luck; thus, finally.

    Shouldn't that be C#? ;)

  • Guy Mahieu (unregistered)

    At least he 'tried'...

  • chriseyre2000 (unregistered) in reply to Paul
    Comment held for moderation.
  • efbiaiinzinz (unregistered) in reply to john
    john:
    the thing that disturbs me the most is that the coder didn´t use a "big" try, finally block but made many of them.

    He wants to ignore every exception anyway so what´s the point in making a try, finally around every single method that could through an exception?

    Well, considering empty finally statement everywhere you could say that all those try{}finally{} statements sum up one big try{}finally{} statement, but I doubt the author meant to use finally statements as they are at all.

    What I suppose from the code is that the author meant to use try{}catch{} catch functionality, but messed up when pasting the code or misunderstood the meaning of finally statement as being an empty catch so there would be no need to write: try{}catch(Exception e1){}, try{}catch(Exception e2){}, try{}catch(Exception e3){} etc. But as far I know C# also supports using catch like try{}catch{} or try{}catch(Exception){}.

    If you use catch statements instead of finally, this code makes sense.

    Imagine if all those changes where in one big try{}catch{}, what happens if the call Server.GetData(Convert.ToInt32(Status.Pending)) returns a null, or has field Results as null.

    You'd get exception and processing will go to catch block, ignoring any next changes += ...; lines in that try block that might have given back some info and increased the value of changes. Same logic applies to any of those count += ...; lines that has another changes += ...; line after it.

    One way to skip that pile of try{} blocks would be to make sure that no null, but at least an empty initalized object that has all required fields initalized is returned, but it would also depend on the application and how it's programmed and whether you would want to know if null was returned or not. So using few try{}catch{} blocks would be the safest and also some sort of lazyest way (no need to start messing around with the Server object code and possibly break something that depends on getting back a null value to do something).

    Therefore to sum up: the author had enough knowledge NOT to put all those line in one try{}catch{} block when trying to get the correct changes value ignoring any exceptions that might have occured on the way and was (at least meant to) preventing some future debugging when there are some changes but they are not shown by neither font color nor the count or the changes count is incorrect. I'd give him an A for being able to foresee such things but F for misunderstanding the meaning of finally statement and trying to use it as an empty catch statement and not knowing that the catch statement can be declared as catch{} :P

  • Tragomaskhalos (unregistered) in reply to Alan
    Alan:
    IMHO C++ does need a finally thanks to the new/delete operators. Oh sure, Java/C# have finally but pretty much everything accessed by java/c# code is automatically managed - unmanaged resources are wrapped in managed objects that make sure dispose/close gets called from the destructor when user code forgets to. C++ does not have that luxury - last pointer goes away and whatever resource it pointed to is never to be reclaimed, closed, or otherwise until exit() (at best) or reboot (at worst) or use some refcounted pointer-wrapper class to prevent those. So, yes, I really think C++ should've had a finally {} before java/.NET did.

    This is wrong. Look up RAII (Resource Acquisition Is Initialization). In idiomatic C++, you don't use "new" (or any other resource acquiring operation) anywhere other than a constructor (or the parameter to a constructor), and you don't use delete (or any other resource releasing operation) anywhere other than a destructor. (Code snipped)

    Exactly so. And whenever I've thought I needed a finally in C++, I've wrapped the resource in a class instead and then realised that I've got a much more elegant and reusable solution. Adding a finally into C++ for the tiny percentage of convenience cases would merely encourage novices to use it all the time instead of RAII, which would be very bad. Also, Alan is wrong to claim that "pretty much everything accessed by java/c# code is automatically managed ". Database connections is a frequently encountered counterexample - tidying these up in Java is an ugly mess compared to the elegance of RAII.

  • MET (cs)
    Java/C# have finally but pretty much everything accessed by java/c# code is automatically managed - unmanaged resources are wrapped in managed objects that make sure dispose/close gets called from the destructor when user code forgets to.
    As a seasoned C++ programmer recently started working in Java I have been very dissapointed by the amount of manual resource managagement. In C++ I use a smart pointer to hold all my resources and so using the RAII idiom I almost never have to worry about manually calling delete or cleaning up objects.

    In Java the finalisers firstly may never be called, and if they are called it is at some indeterminate point in the future. Whereas I need my database connections and other such objects to be released at a specific point regardless of exceptions. This means lots of having to remember to put try...finally blocks round code. Forgetting to do so effectively results in a resource leak. The result is having to be paranoid about resource usage and release, which is something I thought I had left behind with C.

  • x.static (unregistered)

    Bad programming practices aside, the C# compiler will complain loudly if a try block exists without either a catch or a finally.

  • Frank (unregistered) in reply to RadarRider
    RadarRider:
    As noted earlier, that structure allows the code to continue in the face of any exception encountered in the try block. In other words, this may encounter an exception but I don't care; keep going.

    What's interesting is that I've actually seen that technique in at least one C# programming book.

    No, it doesn't. Finally only assures that the code in the finally block gets executed when you leave the try block (either through success or by an exception). It does NOT capture an exception. The code below would do what you want:

    try { MyMethod(); } catch (Exception) { }

  • JackB (unregistered) in reply to john
    john:
    the thing that disturbs me the most is that the coder didn´t use a "big" try, finally block but made many of them.

    He wants to ignore every exception anyway so what´s the point in making a try, finally around every single method that could through an exception?

    It it not the same. When in the same block, if the first statement throws an exception the rest would not be executed

  • larsrc (unregistered)

    I guess that's just one of those subtle differences between Java and C#. In Java, these finally statements would have absolutely no syntactic or semantic effect (depending on the compiler, they might cause an extra JSR/RET in the bytecode). If an exception is thrown, normal control flow would still be interrupted and the exception would propagate as normal. If the code declares exceptions, the method would still be required to declare them -- finally doesn't influence exception declaration at all. Can you actually use try-finally in C# to silence the compiler about declared exceptions?

  • Anon (unregistered)

    First!

    Captcha: gygax (exactly!)

  • Anon (unregistered)

    Damn. Too late!

    Hehe.

    Captcha: scooter (weird, can't think of any context where this would have any relevance)

  • Anon (unregistered)

    Damn. Too late!

    Hehe.

    Captcha: paint (weird, can't think of any context where this would have any relevance)

  • Jon Skeet (unregistered) in reply to larsrc
    larsrc:
    I guess that's just one of those subtle differences between Java and C#. In Java, these finally statements would have absolutely no syntactic or semantic effect (depending on the compiler, they might cause an extra JSR/RET in the bytecode). If an exception is thrown, normal control flow would still be interrupted and the exception would propagate as normal. If the code declares exceptions, the method would still be required to declare them -- finally doesn't influence exception declaration at all. Can you actually use try-finally in C# to silence the compiler about declared exceptions?

    C# and .NET in general don't have checked exceptions, so there's no idea of "declaring" them. There's no difference between C# and Java in terms of the execution of the blocks in the WTF.

  • Fabian (cs) in reply to XIU
    XIU:
    Finally doesn't ignore the exception, it allows you to first do some other code *before* throwing the exception.

    Now that you put it this way, I'm starting to think the keyword "finally" isn't very to the point. How's about "anyway", or "but first", or "before you leave"?

  • JonR (unregistered)

    i'm working with a codebase that is littered with

    try { // blah } catch(Exception e) { throw; }

    this makes me SO ANGRY

  • javascript jan (unregistered) in reply to aquanight
    aquanight:

    In fact, anyone who catches Throwable, Error, or a subclass should have his hands cut off.

    There speaks a man who has never written a service container. Considering the cruft that third parties will throw, you have to have an exception-handling strategy of some fashion when you're dealing with runtime-loaded plugins.

  • mkb (cs) in reply to Marc
    Marc:
    (Minor: "In Java and C++"; should read "and C#"?)

    Actually Microsoft VC++ has a finally extension. Don't know if it's a preprocessor trick or a compiler extension.

  • balu (unregistered) in reply to JonR
    JonR:
    i'm working with a codebase that is littered with

    try { // blah } catch(Exception e) { throw; }

    this makes me SO ANGRY

    Yeah, usually such things are written by people who don't understand that comments don't throw exceptions. Sorry, I couldn't resist...

  • Glenn Lasher (unregistered)

    //First Post messages are a disease. //If one is encountered, throw an exception //and tell the user they are lame

    try { theDailyWTF.postFirstPostMessage(); } catch (lamePostException e) { user.tellToGrowUp(); } finally{}

  • Steve (unregistered) in reply to aquanight
    aquanight:
    You might wonder why one is allocating on the heap an object that might well only be used locally. The heap is generally several times larger than the stack, so there's nowhere better for obsenely large structures. Nevertheless, it's a pain the ass to remember a bunch of deletes before every exit point from the function
    You still don't need try/finally - that's what the auto pointers are for. The auto pointer object goes on the stack, but your real object (that may be very large) goes on the heap. The auto pointer handles the new and delete for you. If the thing you want on the heap is not a simple class instance (eg: binary data of varying length), use a vector.

    Know your STL! If you use the container templates, you can generally get away with not using any explicit 'new' or 'delete' commands at all, and you don't need to catch (or finally) anything for it to be deleted correctly. You should of course still put any allocation into a try/catch block.

    One more thing: no 'properly' written function should have multiple exit points - in theory, at least...

    -- Steve

  • nelle (unregistered)

    finals can be usefull for something like this :

    try { db.openConnection(); db.runSQL( sql ); } catch(SqlException sqlex) { error_panel.ErrorMessage = sqlex.Message; //.Procedure/.Line error_panel.Visible = true; } finally { db.closeConnection(); }

    can someone translate this in c++ with constructors and destructors ...

  • YetAnotherReader (unregistered) in reply to Steve
    Comment held for moderation.
  • YetAnotherReader (unregistered) in reply to nelle
    nelle:
    can someone translate this in c++ with constructors and destructors ...

    try { Connection connection(db.openConnection()); db.runSQL( sql ); } catch(SqlException sqlex) { error_panel.ErrorMessage = sqlex.Message; //.Procedure/.Line error_panel.Visible = true; }

  • brazzy (cs) in reply to Steve
    Steve:
    One more thing: no 'properly' written function should have multiple exit points - in theory, at least...
    IMO a very, very stupid theory that leads to horribly unmaintainable code in many cases.
  • MET (cs) in reply to nelle
    nelle:
    can someone translate this in c++ with constructors and destructors ...
    This is a rough example of the RAII (resource allocation is initialisation) idiom.

    class Connection { public: Connection( Database& db ) : db_( db ) { db_.openConnection(); }

    ~Connection()
    { db_.closeConnection(); }
    

    private: Database& db_; };

    try { Connection db_connection( db ); db.runSQL( sql ); } // connection is automatically dropped on leaving this block catch(SqlException sqlex) { error_panel.ErrorMessage = sqlex.Message; //.Procedure/.Line error_panel.Visible = true; }

    The Connection object may look like coding overhead, but you would use it many times. I assumed the Database object came from somewhere else but if you intended it to be created by the openConnection() call you could obviously remove the constructor argument and add an accessor for the object.

Leave a comment on “Nothing Final”

Log In or post as a guest

Replying to comment #:

« Return to Article