cascading ifs--style question

W

William Pursell

Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

Your thoughts?
 
U

user923005

Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

Your thoughts?

I think it is a mistake to code so that the debugger is happy.

Write it the way that is the most clear. If alternatives are
absolutely equal in your eyes, then choose the one you like (including
the one that makes the debugger happy).
 
F

Flash Gordon

William Pursell wrote, On 16/11/07 04:26:
Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

Your thoughts?

Firstly, I believe in making the code debugger friendly, but only where
it does not make it human unfriendly.

I agree that it is ugly. If it is not function calls you can easily
check the condition of all the variables and sub-expression so you can
see why it has taken or not taken the branch. If b was a function call
there would be more of an argument for separating it out, but not
necessarily conclusive.

Considering all that, I would use the first form.
 
K

Keith Thompson

William said:
Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

If the sub-conditions are really ``a'' and ``b'' (i.e., simple references to
variables), then it doesn't make any difference. If they're, say, function
calls then you can assign them to temporaries.

For example, rather than this:

if (func1() && func2()) ...

you might write this:

int cond1 = func1();
int cond2 = func2();
if (cond1 && cond2) ...

This might be even more readable than the original if you choose sufficiently
descriptive names for the temporaries.
 
J

Joachim Schmitz

Keith Thompson said:
If the sub-conditions are really ``a'' and ``b'' (i.e., simple references
to variables), then it doesn't make any difference. If they're, say,
function calls then you can assign them to temporaries.

For example, rather than this:

if (func1() && func2()) ...

you might write this:

int cond1 = func1();
int cond2 = func2();
if (cond1 && cond2) ...

This might be even more readable than the original if you choose
sufficiently descriptive names for the temporaries.
But is is not the same. In the 1st case func2() may or may not be called,
depeding on the restult of func1(), in the 2nd it will always be called.

Bye, Jojo
 
R

Richard

user923005 said:
I think it is a mistake to code so that the debugger is happy.

Debugger happy is normally reader happy too.
Write it the way that is the most clear. If alternatives are
absolutely equal in your eyes, then choose the one you like (including
the one that makes the debugger happy).

Assuming a and b were expressions I would have at first glance:

aFlag = a();
bFlag = b();

if (aFlag && bFlag)
foo();

We can set watch/break points on conditions for aFlag and bFlag (e.g
only break if aFLag is true and bFlag is false.

But at second glance we realise that (a && b) might be too clever for our
own good. C will not evaluate b() if a() evaluates to false ....

So as the writer of the ORIGINAL code I would have, to make it explicit
what I meant

if(a())
if(b()) /* optimized so as not to call b() if a() fails */
foo();

This is also debugger friendly as we can set a break on the second if().

We could do the intermediate flag trick if we wanted to break on a()
failing(returning false). We can already set a break on foo() when both
conditions are passed.

It is always worth considering debugger/reader friendly code. People
will thank you in the long run.
 
K

Kenneth Brody

William said:
Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

Your thoughts?

Consider, too, the implitations of an else in the above. How
would you handle converting:

if ( a && b )
foo();
else
bar();

to your "debugger friendly" version?

And, I assume you don't really mean "a separate line", because
that would , to me, mean something like this:

if ( a
&& b
)
foo();

Though I have to admit I use such things when the condition gets
complex.

if ( ( some_long_condition
||
another_long_condition
)
&&
yet_another_condition
)
{
do_something;
}

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Kenneth Brody

Keith Thompson wrote:
[...]
For example, rather than this:

if (func1() && func2()) ...

you might write this:

int cond1 = func1();
int cond2 = func2();
if (cond1 && cond2) ...

This might be even more readable than the original if you choose sufficiently
descriptive names for the temporaries.

This isn't the same. If func1() returns zero, func2() wouldn't be
called in the original case.

Consider:

if ( pointer != NULL && *pointer != 0 )

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
F

Flash Gordon

Richard wrote, On 16/11/07 13:39:
Debugger happy is normally reader happy too.

Normally, possibly, but definitely not always.
Assuming a and b were expressions I would have at first glance:

aFlag = a();
bFlag = b();

if (aFlag && bFlag)
foo();

Which behaves differently.
We can set watch/break points on conditions for aFlag and bFlag (e.g
only break if aFLag is true and bFlag is false.

If I needed to do that in debugging I might well make it
if (aflag=a() && bflag=b())
foo();
But at second glance we realise that (a && b) might be too clever for our
own good. C will not evaluate b() if a() evaluates to false ....

It does not take me more than one glance. Also as a lot of C code (and
code in other languages) relies on the short-circuit evaluation I would
say that anyone not comfortable with it is not suitable for work on most
C code.
So as the writer of the ORIGINAL code I would have, to make it explicit
what I meant

if(a())
if(b()) /* optimized so as not to call b() if a() fails */
foo();

This would take me longer to read.
This is also debugger friendly as we can set a break on the second if().

We could do the intermediate flag trick if we wanted to break on a()
failing(returning false). We can already set a break on foo() when both
conditions are passed.

See comment above about using flags with the original format.
It is always worth considering debugger/reader friendly code. People
will thank you in the long run.

Debugger and reader friendly are not always the same, and I find your
alternatives to the original less readable. Someone without much
experience might find your alternatives more readable, but in my opinion
they need to be comfortable with the original to be able to maintain C
code anyway.
 
K

Keith Thompson

Joachim said:
Keith Thompson said:
William Pursell wrote: [...]
instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.
If the sub-conditions are really ``a'' and ``b'' (i.e., simple references
to variables), then it doesn't make any difference. If they're, say,
function calls then you can assign them to temporaries.

For example, rather than this:

if (func1() && func2()) ...

you might write this:

int cond1 = func1();
int cond2 = func2();
if (cond1 && cond2) ...

This might be even more readable than the original if you choose
sufficiently descriptive names for the temporaries.
But is is not the same. In the 1st case func2() may or may not be called,
depeding on the restult of func1(), in the 2nd it will always be called.

Whoops, you're right of course (as is Kenneth Brody who also caught my
mistake).

How about this:

int cond1 = func1();
int cond2 = cond1 && func2();
if (cond2) ...

Again, you really need meaningful names for func{1,2} and cond{1,2}.
 
B

Ben Bacarisse

Flash Gordon said:
If I needed to do that in debugging I might well make it
if (aflag=a() && bflag=b())
foo();

nit-pick: if ((aflag = a()) && (bflag = b()))
 
C

CBFalconer

Flash said:
Richard wrote, On 16/11/07 13:39:
.... snip ...

If I needed to do that in debugging I might well make it
if (aflag=a() && bflag=b())
foo();


It does not take me more than one glance. Also as a lot of C code
(and code in other languages) relies on the short-circuit
evaluation I would say that anyone not comfortable with it is not
suitable for work on most C code.

To duplicate the action of && you need:

if (c = a()) c = b();
if (c) foo();

which you can complicate into aflag and bflag, replacing the final
c with a computation.
 
C

Charlie Gordon

William Pursell said:
Lots of discussion lately on coding so that the debugger
stops on each line, and this is yet another. In that debate,
I fall in the camp of those who like code written such that
every statement is on a separate line (although I can't
stop using :?). I am curious to get opinions on the following
style:

instead of:
if( a && b )
foo();

use:
if( a )
if( b )
foo();

This style puts the conditionals on separate lines, so it
has that in its favor. But me thinks it has very few other
redeeming features and is a bit ugly.

Your thoughts?

If you are going to do this for debugging purposes, at least use proper
indentation and bracing to avoid stupid errors:

if (a) {
if (b) {
foo();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top