Stuart said:
Why isn't it the same? It's still a jump to a label.
A jump may be involved, but GoTo is unconditional, while On Error Goto
is conditional. So at least in case of an On Error GoTo, we know that a
error occurred. With GoTo, it can be for any reasons and we'd have to go
back to find where the GoTo came from. If it came from multiple points,
then that's more time figuring which/when we reach this label from which
GoTo.
Why must I justify using a command that's built into VBA? One could argue
that the only reason it's still part of the language is for error handling,
but then GoSub is still there also (which I use sparingly too). Both
commands provide branching within the scope of a procedure without the
overhead of building a stack frame with (sometimes loads of) parameters and
calling external code. This can in some cases improve execution time.
I'm a big fan of "Just because you can, doesn't mean you should." VBA
has many constructs built in for different reason, and I would bet that
it has GoSub...Return and GoTo as a backward compatibility for old
projects that had no choice but to use those. But that's not an argument
for using them right now, I would think.
With regards to code efficiency, this subject was much more important
when we were working with a handful of hertz cycles, few bytes of memory
but I don't think this is the case anymore. It used to be that
tweaking a code to overflow and thus save on a conditional check or
turning to assembly language would make a material difference, but
nowadays most modern programming languages would trade in efficiency for
reliability by enforcing type-safety, and typing strongly as well doing
more checks. I don't imagine that those would run slower in comparison
to C language. But that meant programmers could deliever a better
quality program with less effort and time. In fact, that's exactly the
premise VB/VBA was based on. It never was meant to be the most efficient
language, just practical.
Not to say that efficiency is now totally irrelevant; there are time
where a piece of code must be optimized, definitely. But I don't think
I've had a case where big performance gains was achieved by using a
GoSub...Return instead of a separate procedure call.
And efficiency isn't always measured in one way (e.g. numbers of
instruction required to execute this piece of code). It can be also
measured in how easy it is to maintain or enhance a program. I would say
that constructs such as GoTo and GoSub...Return actually harm the
efficiency because the procedure is not modular that I can't just stick
in a new feature without undesirable side effects or optimize the code
without changing the output to something undesirable.
So for those reasons, I don't think I would want to use such constructs.
Er.. before the handler is reached there should definitely be an Exit
Sub/Function statement, which means that error handling code should never
execute from normal sequential means. But I do agree that not being able to
use the call stack will sometimes be a disadvantage. That's one of the
reasons I advised to use with caution (but neglected to mention).
Actually, I think Dirk wasn't talking about error handling anymore but
rather the unconditional GoTo, like this:
If something Then
...
GoTo A
Else
...
End If
If anotherthing Then
A:
...
End If
....
How did we get to A? Was it because we passed the anotherthing test or
because we got there from the GoTo in the something test? That's one
guess I'd rather not make.