← Back to context

Comment by cerved

6 days ago

To anyone wondering, I believe it's cursed because the finally continue blocks hijacks the try return, so the for loop never returns

So the function returns, and then during its tidyup, the 'continue' basically comefrom()s the VM back into the loop? That is, indeed, cursed.

  • I would not call this snippet particularly "cursed". There is no "aktshchually this happens, therefore this is activated" hidden magic going on. The try-catch-finally construct is doing exactly what it is designed and documented to do: finally block is executed regardless of the outcome within try. The purpose of finally block is to fire regardless of exceptionality in control flow.

    Surprising at first? Maybe. Cursed? Wouldn't say so. It is merely unconventional use of the construct.

    • It messes with the semantics of "return" statement. The conventional intuition is that right after a "return" statement completes, the current method's invocation ends and the control returns to the caller. Unfortunately, the actual semantics has to be that is "attempts to return control":

          The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.20) within the method or constructor whose try blocks or catch clauses contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.
      

      This, I believe, is the only way for "return E", after the evaluation of E completes normally, to not return the E's value to the caller. Thanks for a needless corner-case complication, I guess.

      9 replies →

    • Sufficiently unexpected (surprising) is cursed. If anything, that’s the way most people use that term for programming language constructs (weird coercions in JavaScript, conflicting naming conventions in PHP, overflow checks that get erased by the compiler due to UB in c/c++, etc.)

      6 replies →

    • It's been many, many moons since I touched Java but I would have expected this to run the finally { } clause and then return from the function (similar to how in C++, objects on the stack will run their destructors after a return call before the function ends. I certainly wouldn't expect it to cancel the return.

see, if you only had GOTO's, this would be obvious what is going on!