Re: Question on vector at()
On Mar 17, 12:33 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
I couldn't have responded better than James did. One note, though:
On Mar 17, 3:22 am, Jeff Schwab <j...@schwabcenter.com> wrote:
By the time you see a stack trace, you're already working
backwards. The best tools for finding and tracking logical
errors are compilers and unit tests. It is uncanny how the
people who are best with the debugger are the worst
developers. (That's not meant as a dig at you, btw; I have no
idea what your day-to-day code looks like, and I'm not in a
position to criticize it.)
I honestly can't understand this opinion.
Developers are humans, and humans make mistakes. No matter how
experienced you are at developing, even if you are the best
C++ developer in the world and your code has the best quality
in the world, you will make small mistakes here and there from
time to time.
Totally agreed up until there.
The vast majority of these small mistakes can be found with a
proper debugger almost immediately.
That's not really my experience. First, you need exhaustive
unit tests, regardless. And typically, if you understand the
code you've written, and the unit tests are well designed, and
address all possible failure modes explicitly, then you'll know
pretty much what the error is just from the unit tests---you
don't need the debugger. (As a general rule. There are
exceptions, and as I posted, I encountered a case where the
debugger really helped just a couple of days ago. But it's the
first time in about 20 years.)
Secondly, there's strength in numbers. While everyone makes
mistakes, typically, each person will overlook something
different. So the people doing code review will catch those
that you missed. And catch the cases you forgot to test in your
unit tests. My experience is that when code review is done
correctly, you typically get something like one error per
100,000 lines of code going into integration. (It's possible to
get even less, but at some point, trying to eliminate that very
last error ceases to be cost effective, unless you're dealing
with truely critical software.)
You simply have to see the line where the program crashed in
order to immediately see your own mistake and fix it.
OK. When people talk about "using a debugger", I generally
think in terms of interactive execution of the program. I agree
that it's very useful for post-mortems.
Without the aid of a debugger it could take tens of minutes,
or even hours at worst. ("Segmentation fault" is not a very
informative error message. Having to find the place where the
fault happens by adding debugging prints to your program can
be a real pain.)
Segment fault leaves a core dump, which can be used in a post
mortem analysis. (At least it does on the machines I work on.)
If the error is not exactly at the line where the crash
happened, the debugger is even more useful, exactly because of
the stack trace. You can navigate the call stack down until
you find the actual place where the error happened, you can
easily examine the values of the variables at that place, and
in the majority of the cases you will immediately see what the
problem was (usually a small typo or thought mistake).
So are you talking about a post-mortem, or executing the program
under the debugger?
It is, of course, possible to have really nasty bugs which are
extremely hard, or even impossible, to find with just a
debugger. However, that doesn't mean that the debugger isn't
useful.
If I had to develop C++ programs without any kind of debugger,
it would be a real pain.
I've had to do it with C. It's not that bad. The real problem
is the absense of the ability to do a post-mortem.
Each small mistake, each small typo, would require a long and
laborious task of manually adding debug prints to try to
binary-search the location of the error...
It does mean rerunning the program with full logging activated.
Horrible.
(I have actually had to do this in the past, when developing
programs in a Unix environment using gcc and without gdb or
any other kind of debugger. It was not nice.)
One important point: when there is an error in delivered code,
your first job is to reproduce it in the unit tests. Normally,
if the program is adequately instrumented (logging, etc.), you
should be able to do this uniquely from the log data. And once
you've done it, we fall into the case I first cited, above: the
way the unit test fails pretty much indicates where the error
is. Whatever you do, of course, you do NOT correct an error in
the code until you have a unit test which reveals it.
Of course, all of my comments above are general rules. As any
experienced programmer knows, there will be special cases which
just don't fit in, and stubborn errors which slip through code
review, and which require use of the debugger just to find the
failure mode, so you can test it. Such cases are, or should be,
very rare, however, and one should resist the temptation to run
the program under the debugger just because you don't understand
anything. (As a general rule: unless you can state precisely
what you want to look at, and what you should see, or expect to
see, it's too early to break out the debugger.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34