 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Frank Birbacher Guest
|
Posted: Sun Nov 21, 2004 11:31 pm Post subject: coding for debugging? |
|
|
Hi!
One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ilmari Krebs Guest
|
Posted: Mon Nov 22, 2004 11:10 am Post subject: Re: coding for debugging? |
|
|
the second form of isSquare is also easy debuggable. the code should be easy to read and comprehensible.
do you really model a Square by using a Rectangle class?
or are you going to show in your class that this kind of design
have a lot of pitfalls?
Greetings,
Ilmari
| Quote: | Frank Birbacher<bloodymir.crap (AT) gmx (DOT) net> Monday, November 22, 2004 12:31:32 AM
Hi! |
One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Mon Nov 22, 2004 11:10 am Post subject: Re: coding for debugging? |
|
|
Frank Birbacher wrote:
| Quote: | One of my students, he is somewhat experienced, turned in
the following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated"
way. I would have written (const and throw() aside, they
don't have it in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help
debugging. Being able to set a single breakpoint at the
only one return statement and being able to see the
status of all local variables at that point would be
important for debugging.
|
He can set a conditional breakpoint.
| Quote: | Now I would still not use a
dedicated result variable for such simple functions
(keeping in mind to make functions as easy as possible),
as I didn't have these problems during debugging yet. So
my question is: is it a good habit to code that way (1st
piece of code) and support the debugger where it comes
short? Or should code be rather short and simple (2nd
piece of code)?
|
IMOH short and simple. If he finds that he needs to work
around certain limitation in his debugging tools, he can
temporarily rewrite the piece to the first form, when need
arises.
BR
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler (ne Spange Guest
|
Posted: Mon Nov 22, 2004 11:11 am Post subject: Re: coding for debugging? |
|
|
Hello Frank Birbacher ,
Frank Birbacher schrieb:
| Quote: | One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
|
I really prefer the second approach. I have seen code like (1) in MFC
code, but to
my opinion, modern compilers are both able to
(A) break at an return statement.
(B) present me the contents of any local/member/global variables in
sufficient detail
The very reason for ansatz (1) seems to be that with compilers which
support something
like "set next statement" I am able to do an artifically jump, which
either skips the conditional
or unconditionally sets the conditional result. Even this kind of
debugging is realizable if
we change (2) to
bool Rectangle::isSquare()
{
bool result(height==width);
return result;
}
if the very same compiler supports modifications of variables (I don't
know of one I use which
doesn't).
Greetings from Bremen,
Daniel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Vecerina Guest
|
Posted: Mon Nov 22, 2004 11:14 am Post subject: Re: coding for debugging? |
|
|
"Frank Birbacher" <bloodymir.crap (AT) gmx (DOT) net> wrote
| Quote: | One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging.
Well, one should still at least make it a 2-line function: |
bool result = (height==width);
return result;
| Quote: | Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
I'd keep it short and simple, especially since my debugger allows |
me to see the return value at the call point, and within the function
I can easily view height and width myself.
While this is a matter of style, most experienced developers will
prefer the more compact version (better signal/noise ratio).
I also think that even a novice programmer should learn to use
the result of a comparison operator directly as a bool value:
b = ( x==y );
and not:
b = false;
if( x==y ) b = true;
The clutter in the second option cannot be justified IMO.
Regards,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Mon Nov 22, 2004 11:19 am Post subject: Re: coding for debugging? |
|
|
"Frank Birbacher" <bloodymir.crap (AT) gmx (DOT) net> wrote...
| Quote: | One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
|
FWIW, his claim is somewhat self-debunking. The function doesn't need
and therefore doesn't have local variables to begin with. His alleged
claim is that he needed to see "local variables" "for debugging" is
somewhat strange, why would one need to introduce local variables just
to see local variables? Now, if he did claim a need to see _member_
variables, I might actually believe him, but local? No.
As to writing code suitable for debugging, he's right. It is sometimes
important to write the code to make it suitable for debugging. I have
seen this:
int SomeClass::SomeMember(int somevalue) const
{ return somearray[somevalue]; } // line 155
recently as a good example. When the breakpoint was set to the 'return'
statement (on the line 155), the debugger did actually understand to set
it at the opening curly brace. A colleague of mine was looking for the
source of some error and couldn't understand why in the calling function
the argument of the 'SomeMember' was fine, with the value 1, while when
the debugger stopped at the beginning of that function ('SomeMember'),
his attempt to display 'somevalue' gave him some outrageously incorrect
large number.
Well, the explanation was simple: when the execution was stopped, the
context of the function 'SomeMember' hasn't been set up yet. It would
be only set up _after_ he stepped over the opening curly brace. But
that would execute the 'return' statement and he'd not be able to see
the contents of 'somevalue' anyway.
The solution was to rewrite the code to separate the opening curly brace
and the 'return' statement:
int SomeClass::SomeMember(int somevalue) const
{
return somearray[somevalue]; }
after which, with the breakpoint set on the 'return' statement he could
gladly see that 'somevalue' (the argument) was 1 inside the function as
well.
One could write it off as a drawback of the debugger that couldn't step
over more than one statement on a line, but that's a different story.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Phlip Guest
|
Posted: Mon Nov 22, 2004 11:21 am Post subject: Re: coding for debugging? |
|
|
Frank Birbacher wrote:
| Quote: | One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
|
A full-featured debugger can express the simpler version of the code with
its "quick watch" facility.
Further, all students should learn to write test harnesses for their code,
at the same time as they write the code. Questions about code's behavior
should be answered by writing new tests. Proactive testing makes a debugger
less needed.
--
Phlip
http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Nov 22, 2004 9:35 pm Post subject: Re: coding for debugging? |
|
|
Frank Birbacher <bloodymir.crap (AT) gmx (DOT) net> wrote
| Quote: | One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I would
have written (const and throw() aside, they don't have it in class
yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being able
to set a single breakpoint at the only one return statement and being
able to see the status of all local variables at that point would be
important for debugging. Now I would still not use a dedicated result
variable for such simple functions (keeping in mind to make functions
as easy as possible), as I didn't have these problems during debugging
yet. So my question is: is it a good habit to code that way (1st piece
of code) and support the debugger where it comes short? Or should code
be rather short and simple (2nd piece of code)?
|
Several comments:
- Even if I wanted the separate variable, I would initialize it with
height == width, and not use an if.
- I would expect any debugger to allow viewing height and width. If
you can see the current values of height and width, and can't figure
out what the function is going to return, I rather think you have a
problem.
- I would not allow students to use a debugger. No point in letting
them get into bad habits.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Mon Nov 22, 2004 9:57 pm Post subject: Re: coding for debugging? |
|
|
[email]bloodymir.crap (AT) gmx (DOT) net[/email] (Frank Birbacher) wrote (abridged):
| Quote: | So my question is: is it a good habit to code that way (1st piece
of code) and support the debugger where it comes short? Or should
code be rather short and simple (2nd piece of code)?
|
In this case I would write the simpler version. I see very little merit in
having a single exit point - I can easily add multiple break points, and
my debugger can break "on exit" anyway. I prefer to avoid spurious mutable
state.
However, I sometimes prefer "if" tests to conditional expressions, or to
complex expressions with &&. That is mainly because I think they can be
easier to read, but ease of debugging is a factor too. For example:
int get() {
if (condition1() || condition2())
if (condition3())
return first();
return second();
}
versus:
int get() {
return ((condition1() || condition2()) && condition3()) ?
first() : second();
}
With my debugger the first form is easier to debug, because it lets me put
a break point on any line but not on sub-expressions within a line.
I don't think this is compromising simplicity for the sake of
debugability, because I think the first version is clearer anyway. What's
good for the debugger is also good for humans. If the case when
condition1() or condition2() is true is significant enough to merit a
break point, it is worth highlighting in the code, too, and not buried in
some larger expression.
An even simpler case is:
int MyClass::get_x() const { return x; }
I would split this over multiple lines:
int MyClass::get_x() const {
return x;
}
purely to help the debugger. The second form admits 3 break points and the
first form only 1. So I do think "writing for the debugger" is sometimes
OK. However, even in this case I don't think readability is actually
compromised.
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Branimir Maksimovic Guest
|
Posted: Mon Nov 22, 2004 9:58 pm Post subject: Re: coding for debugging? |
|
|
Frank Birbacher <bloodymir.crap (AT) gmx (DOT) net> wrote
| Quote: | Hi!
One of my students, he is somewhat experienced, turned in the
following code:
bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging. Now I would still not use
a dedicated result variable for such simple functions (keeping in
mind to make functions as easy as possible), as I didn't have
these problems during debugging yet. So my question is: is it a
good habit to code that way (1st piece of code) and support the
debugger where it comes short? Or should code be rather short and
simple (2nd piece of code)?
|
This does not have anything to do with debugger.
It's just a matter of style.
Perhaps he meant to write
bool Rectangle::isSquare()
{
if(height==width)return true;
else return false;
}
in such cases placing temporary result variable would mean single point
of return; but not in this case as you showed in second example.
Perhaps better example would be:
template<class iterator, class value>
bool is_it_there(iterator first,iterator last, value v)
{
while(first!=last)if(*first++ == v)return true;
return false;
}
or
template<class iterator, class value>
bool is_it_there(iterator first,iterator last, value v)
{
bool rc = false;
while(first!=last)
{
if(*first++ == v)
{
rc = true;
break;
}
}
return rc;
}
IMO it's still just a matter of style. Some programmers like one way
and others, other.
Greetings, Bane.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
dietmar_kuehl@yahoo.com Guest
|
Posted: Mon Nov 22, 2004 10:00 pm Post subject: Re: coding for debugging? |
|
|
Frank Birbacher wrote:
| Quote: | bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
|
I can see why there is need for debugging in the first case: it
is sufficiently complicated to slip in unintended programming
errors. Put differently, I would use the second form because it
is more likely to be correct in the first place and thus the need
for debugging is reduced right off the mark. I think writing
correct code is a much bigger help with respect debugging...
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
L.Suresh Guest
|
Posted: Mon Nov 22, 2004 11:03 pm Post subject: Re: coding for debugging? |
|
|
I have experienced the same scenario lots of times. Big pain to
rewrite it and then start debugging again. sometimes the results can
be found in the debugger itself. (the debugger shows the last returned
value from the function). sometimes it can be inferred easily, you can
see the values of height, width and then calculate the results.
Personally i feel that it should be short and simple because debugging
is not the usual scenario for the code, you do it when you need to
ascertain that the program actually does what you intended it to do. I
usually assert liberally when i want to ascertain states, invariants
etc.,
-lsu
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Mon Nov 22, 2004 11:07 pm Post subject: Re: coding for debugging? |
|
|
[email]v.Abazarov (AT) comAcast (DOT) net[/email] (Victor Bazarov) wrote (abridged):
| Quote: | FWIW, his claim is somewhat self-debunking. The function doesn't need
and therefore doesn't have local variables to begin with. His alleged
claim is that he needed to see "local variables" "for debugging" is
somewhat strange, why would one need to introduce local variables just
to see local variables? Now, if he did claim a need to see _member_
variables, I might actually believe him, but local? No.
|
He might mean temporaries. My debugger (VC++7.1) treats temporaries as
second class citizens. For example, comparing:
SomeObject *make() {
return new SomeObject;
}
with:
SomeObject *make() {
SomeObject *p = new SomeObject;
return p;
}
the latter is easier to debug. With the former, the debugger will show
the result of operator new as a single line but won't let you drill into
it, nor can you add it to a watch window etc.
Despite this I would use the shorter form by default, and rewrite it if
and when necessary. That's because I can - I usually have write access to
the source I need to debug, and I can usually recompile and reproduce bugs
quickly. If I were writing library code for 3rd parties, I might change my
style. I've occasionally wished my local std library was more
debugger-friendly. Getting something as simple as the size of a
std::vector<int> is a pain.
Even though I don't really agree in this case, I can sympathise with
someone who has a consistent style and wants to use it in all cases, even
for simple routines where it is not really necessary.
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Chris Uzdavinis Guest
|
Posted: Mon Nov 22, 2004 11:12 pm Post subject: Re: coding for debugging? |
|
|
Frank Birbacher <bloodymir.crap (AT) gmx (DOT) net> wrote
| Quote: | bool Rectangle::isSquare()
{
bool bResult = false;
if(height==width)
bResult = true;
return bResult;
}
I asked him, why he is doing it in such a "complicated" way. I
would have written (const and throw() aside, they don't have it
in class yet):
bool Rectangle::isSquare()
{
return height==width;
}
He said, he learnt it that way and it would help debugging. Being
able to set a single breakpoint at the only one return statement
and being able to see the status of all local variables at that
point would be important for debugging.
|
In order to inspect a local variable, the student needs a local
variable. It's hard to argue against that logic. :)
But the point isn't trying to debug a local variable. The point is
trying to determine if the function returns the correct value. The
local variable is not fundamental to the calculation, and is only
useful because the author doesn't know other ways to debug such a
function. It's not necessary.
Most debuggers allow you to see the function's return value by itself,
either in a special view or by looking at the registers. On X86, for
example, it's usually in EAX register. But even easier is to debug
the return value of the function by debugging the calling code rather
than the function itself.
This is an excellent opportunity to introduce the concept of unit
testing!
--
Chris
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Torjo Guest
|
Posted: Tue Nov 23, 2004 10:45 am Post subject: Re: coding for debugging? |
|
|
| Quote: | [...]
yet. So my question is: is it a good habit to code that way (1st piece
of code) and support the debugger where it comes short? Or should code
be rather short and simple (2nd piece of code)?
- I would not allow students to use a debugger. No point in letting
them get into bad habits.
|
While I would definitely go with the 2nd version (also, for some of
the reasons already pointed out), I don't understand why do you think
using a debugger is a bad habbit.
When you need to solve bugs, debugging and logging are two very useful
tools.
Best,
John
--
John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.6 - documentation, bitmap buttons, tab dialogs, lite html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|