With break, control flow goes out of the loop or out of the switch. You may find function calls there. With continue, control flow goes to the start of the loop. You may find function calls there. With return, control goes through the defer blocks and then out of the function. Similar reasoning for goto. In every case, you know where the control flow goes by looking at the context inside the function.
I don't agree with the assessment that one of them is more hidden than the other.
>With break, control flow goes out of the loop or out of the switch. You may find function calls there.
Yeah but you don't have to look for anything in between. You look for where it goes, and that's it. That there could be a function call after the continue has executed isn't relevant at all, there could also be function call after a return has executed. Stepping through the code in your head is trivial because the execution never jumps anywhere without an explicit statement to jump.
With defers, you need to make sure you find every single defer that was executed up to the return (which might not be trivial if defers are executed conditionally). With a break there is exactly one, unconditional, position at which execution continues - and if you have found it, there is no reason to keep looking anywhere else.
I mean wanting to make the defer trade-off but not the destructor trade-off, fine, that is ultimately a matter of opinion. But defer being hidden control flow is just objectively true, execution jumps somewhere without a corresponding explicit jump in the code (return only explicitly jumps out of the function).
I don't agree with the assessment that one of them is more hidden than the other.