As others have pointed out, this indicates that your function is
probably too long to be well-understood.
That means looking at every line of code before that point,
I suppose so, but it's the backward-search feature of my text editor
that does the looking, it's not at all tedious for me.
... for a variable
name that be similar to many others.
Similarity doesn't matter to the backwards-search feature. Just cut and
paste the variable name into the search pattern, and you'll guarantee
it's the one you're looking for. If you can't find it, there's been a
misspelling. Choose the "whole words only" option (if available in your
editor), and you won't have to worry about false positives from other
identifiers whose names contain that variable's name.
... Declarations at the start of a function
are easier for low-tech editors (even with one that can't switch quickly
between two locations, probably you can run two instances of it).
My favorite editor (vi) is fairly low tech, and available just about
everywhere I need it; you may be less lucky. I don't think anyone should
settle for using a editor on a modern (in this case, modern means post
1980's) system that's not capable of backwards search.
Note: I would not recommend vi for new users; the learning curve is
quite steep, GUI editors are much easier to use, particularly if built
into an IDE. However, I've already learned it, and once you've learned
them, the power of vi's commands can be quite addictive. I've never seen
a GUI editor (other than gvim, which doesn't really count) where I could
do all (or even most) of the things I can do with vi commands.
Look at this example from the middle of a function (from Python sources):
mz = z->ob_type->tp_as_number;
Applying a local declaration, and let's say you're lucky and this the first
use of mz you see, it might look like:
PyNumberMethods mz = z->ob_type->tp_as_number;
That's great; we know what mz is. Except that's not the full picture. The mz
variable is actually declared like this at the top of the function:
PyNumberMethods *mv, *mw, *mz;
Now we know there are three related variables, and there aren't any called
mx or my. Which can give an extra dimension to our knowledge (there are
parameters v, w, z, and mv, mw, and mz presumably correspond to these). It
also tells us that mx and my are available for other purposes.
With a smart IDE, and careful perusal, you would become aware of all this
anyway. But burying the details about local variables in a dozen assorted
places just obfuscates things and life a bit more difficult.
My experience is the opposite. Putting declarations closer to the point
of use highlights them, it doesn't bury them in a huge pile of other
variables. Knowing that a given variable will be used only in one
particular inner scope makes it easier to understand it's meaning, not
harder.
Of course, the best way to document the meaning of a variable is with a
comment on the line where it's declared, or if there's not enough room
for that, on the previous or following line (it doesn't matter which,
but it does matter that the choice of 'previous' or 'following' be
consistent throughout a given body of code).
I was going to say that making in-place declarations makes things easier to
write, harder to read, but then imagine having to clutter your code with
three lots 'PyNumberMethods' instead of one!
I often will do that even if they were all declared at the top of the
same block; only if they were all closely related variables of the same
type with short names would I merge their declarations like that. And if
those conditions are met, I'd carefully consider whether they should be
elements of a single array, rather than separate variables.
Using multiple declarations also often allows enough room for a short
descriptive comment on the declaration line.