Re: Coding standards
Natt Serrasalmus wrote:[color=blue]
> "infobahn" <infobahn@btint ernet.com> wrote in message
> news:cqr5if$1i3 $1@sparta.btint ernet.com...
>[color=green]
>>jdallen2000@y ahoo.com wrote:
>>[color=darkred]
>>>Similarly, in C we always write "if (foo(bar))" without
>>>debating whether "if( foo (bar))" is better a priori.[/color]
>>
>>Which "we" are you talking about? It doesn't include me.
>>
>>I write if(foo(bar) != 0)[/color]
>
>
> I find that form really annoying[/color]
I don't.
[color=blue]
> and when I see it in others code. It
> suggests to me that the person who wrote it doesn't understand boolean
> variables and the C idiom that was established with the C standard library.[/color]
You are wrong to infer that. I do in fact understand boolean variables.
I also understand that in almost all cases, foo() does not return a
boolean variable, but an int. If foo() is truly boolean in nature,
then I am perfectly prepared to write if(foo(bar)) rather than
if(foo(bar) != 0)
But the fact that you find the form "annoying" suggests that you need to
relax a little.
[color=blue]
> The idiom I am referring to is that functions should return a value that
> answers the question "Did anything go wrong and if so what was it?".[/color]
Absolutely. And a boolean variable can only answer one of those
questions, which is why so few of my functions return boolean
variables.
[color=blue]
> By that
> idiom then it should be obvious to any C programmer worth their pay that
>
> if(strcmp(strin g1, string2))
>
> means "Did anything go wrong (not match up) when comparing these two
> strings?"[/color]
No, it should be obvious to any C programmer worth their pay that
the result of strcmp is not boolean, but relational (negative,
zero, or positive).
[color=blue]
> (if I wanted to know how far off they were I'd save the return
> value to a variable and evaluate that, but rarely does anyone ever care how
> far off the comparison was, other functions may have more interesting
> non-zero return codes.)[/color]
We do, however, care whether the result is negative, zero, or positive.
[color=blue]
> This form also encourages the early exit from a function:
>
> if(strcmp(strin g1, string2))
> return;[/color]
I, however, do not encourage early exit from a function. In all too
many cases, this makes the control flow harder for a maintenance
programmer to follow. Maintenance programmers are often under a lot
of pressure to fix a problem quickly, in code they don't know very
well. Anything we can do to help them out is a bonus, and writing
your functions to have all the structure of spaghetti bolognaise is
not helping anyone.
[color=blue]
> If you doubt me, look at K&R where you can find numerous examples of this
> form and the early exit from functions.[/color]
But nobody has to maintain the code in K&R's book. Also, whilst I
greatly admire both K, R, and their book, the day I use K&R as a
style guide is the day I grow an extra arm.
[color=blue]
> This may seem awkward at first, but you get used to it.[/color]
I am fortunate enough not to have got used to early exit from functions.
I am very happy for you if you are used to it, but I have developed my
own style based on my own reasoning and logic, and I'm quite happy to
use that style.
Your style for you; my style for me.
[color=blue]
> You should also get
> used to writing your own functions in the same idiom, such that they return
> zero for success and non-zero (with a value that indicates the level of
> failure) for failure. This will preserve the idiom throughout the code.[/color]
Oh, I do that already, and have done for many years.
[color=blue]
> A similar form that is particularly annoying is
>
> if(foo(bar) == TRUE) /* where true is a macro defined as some non-zero
> value */[/color]
There, I must agree with you. What makes this worse is when foo() is not
a boolean function, and yet its result is still compared against a
"boolean" symbol such as TRUE or FALSE.
[color=blue]
> {
> (indented code for the entire rest of the function)
> }
> return somestatusvaria ble;[/color]
Oh, I see. You're complaining against code structure.
[color=blue]
>
> when it should be
>
> if(!foo(bar))
> return NONZEROSTATUSVA LUE;
> (code for the entire rest of the function now not indented so far)[/color]
I prefer:
if(foo(bar))
{
rc = baz();
}
else
{
rc = NONZEROSTATUSVA LUE;
}
return rc;
Do you have a problem with the nesting depth here?
[color=blue]
> (note also that some may have different notions as to what TRUE should be
> defined as: -1, 1 etc. which makes the test against TRUE not just
> idiomatically awkward, but potentially dangerous.)[/color]
Yes, that's what I thought you meant before.
[color=blue]
>
> Even worse is
>
> if(a == b)
> {
> c = TRUE;
> }
> else
> {
> c = FALSE;
> }
>
> which should be
>
> c = a == b;[/color]
This code, whilst correct, will have the newbies (and some older hands)
reaching for their K&Rs. Better: c = (a == b);
[color=blue]
>
>
> or even worse than that
>
> if(a == b)
> {
> c = FALSE;
> }
> else
> {
> c = TRUE;
> }
>
> which should be
>
> c = !(a == b);[/color]
I would prefer c = (a != b);
[color=blue]
> Some of you may be laughing at these last two examples, but don't. I've seen
> it too many times that it's not funny any more.[/color]
I didn't find them particularly funny. Just silly.
<snip>
[color=blue][color=green]
>>
>>Hardly. It's a common style, but its mindshare seems to be diminishing.[/color]
>
>
> I hope its mindshare is dimishing. I would have written the above as:
>
> if (!cap_issubset( inheritable,
> cap_combine(tar get->cap_inheritabl e,
> current->cap_permitted) ))
> goto out;
>[/color]
Mmmm. Well, just pray you never have to maintain my code.
[color=blue]
> This way arguments to functions are lined up.[/color]
Not in my newsreader, they aren't.
[color=blue]
> There's no need for any braces
> at all,[/color]
Well, the compiler doesn't need them. The human sometimes finds them
useful, so I put them in /all/ the time.
[color=blue]
> so leave them out leaving fewer braces to worry about which ones
> match which.[/color]
For a start, they should be close enough together that you can
see which ones match which other ones. And even if they aren't,
if you line them up
{
like this
}
you don't have to worry about which ones match which, because it's
obvious. And even if it weren't obvious, decent modern editors can
whizz you from { to } and back in the blinking of an eye.
<snip>
[color=blue][color=green][color=darkred]
>>>I know almost nothing about the `indent' utility. Can it produce
>>>the spacing above automatically? And suppress it when shorter
>>>names make it unnecessary? I know about `#ifndef lint'; is there
>>>some sort of `#ifndef indent' when one wants to preserve a helpful
>>>white-space arrangement?[/color]
>>
>>The whole point of indent is that you run code through it to
>>convert it to your style, making it easier for you to read.
>>Then, if you need to check it back into CVS, you run the
>>code through it again, this time to convert it to the house
>>style. That way, you don't screw up diff with mere whitespace
>>changes, and everyone's happy. Bye bye holy war.[/color]
>
>
> I do agree with you on that.[/color]
Hallelujah, and amen.
Natt Serrasalmus wrote:[color=blue]
> "infobahn" <infobahn@btint ernet.com> wrote in message
> news:cqr5if$1i3 $1@sparta.btint ernet.com...
>[color=green]
>>jdallen2000@y ahoo.com wrote:
>>[color=darkred]
>>>Similarly, in C we always write "if (foo(bar))" without
>>>debating whether "if( foo (bar))" is better a priori.[/color]
>>
>>Which "we" are you talking about? It doesn't include me.
>>
>>I write if(foo(bar) != 0)[/color]
>
>
> I find that form really annoying[/color]
I don't.
[color=blue]
> and when I see it in others code. It
> suggests to me that the person who wrote it doesn't understand boolean
> variables and the C idiom that was established with the C standard library.[/color]
You are wrong to infer that. I do in fact understand boolean variables.
I also understand that in almost all cases, foo() does not return a
boolean variable, but an int. If foo() is truly boolean in nature,
then I am perfectly prepared to write if(foo(bar)) rather than
if(foo(bar) != 0)
But the fact that you find the form "annoying" suggests that you need to
relax a little.
[color=blue]
> The idiom I am referring to is that functions should return a value that
> answers the question "Did anything go wrong and if so what was it?".[/color]
Absolutely. And a boolean variable can only answer one of those
questions, which is why so few of my functions return boolean
variables.
[color=blue]
> By that
> idiom then it should be obvious to any C programmer worth their pay that
>
> if(strcmp(strin g1, string2))
>
> means "Did anything go wrong (not match up) when comparing these two
> strings?"[/color]
No, it should be obvious to any C programmer worth their pay that
the result of strcmp is not boolean, but relational (negative,
zero, or positive).
[color=blue]
> (if I wanted to know how far off they were I'd save the return
> value to a variable and evaluate that, but rarely does anyone ever care how
> far off the comparison was, other functions may have more interesting
> non-zero return codes.)[/color]
We do, however, care whether the result is negative, zero, or positive.
[color=blue]
> This form also encourages the early exit from a function:
>
> if(strcmp(strin g1, string2))
> return;[/color]
I, however, do not encourage early exit from a function. In all too
many cases, this makes the control flow harder for a maintenance
programmer to follow. Maintenance programmers are often under a lot
of pressure to fix a problem quickly, in code they don't know very
well. Anything we can do to help them out is a bonus, and writing
your functions to have all the structure of spaghetti bolognaise is
not helping anyone.
[color=blue]
> If you doubt me, look at K&R where you can find numerous examples of this
> form and the early exit from functions.[/color]
But nobody has to maintain the code in K&R's book. Also, whilst I
greatly admire both K, R, and their book, the day I use K&R as a
style guide is the day I grow an extra arm.
[color=blue]
> This may seem awkward at first, but you get used to it.[/color]
I am fortunate enough not to have got used to early exit from functions.
I am very happy for you if you are used to it, but I have developed my
own style based on my own reasoning and logic, and I'm quite happy to
use that style.
Your style for you; my style for me.
[color=blue]
> You should also get
> used to writing your own functions in the same idiom, such that they return
> zero for success and non-zero (with a value that indicates the level of
> failure) for failure. This will preserve the idiom throughout the code.[/color]
Oh, I do that already, and have done for many years.
[color=blue]
> A similar form that is particularly annoying is
>
> if(foo(bar) == TRUE) /* where true is a macro defined as some non-zero
> value */[/color]
There, I must agree with you. What makes this worse is when foo() is not
a boolean function, and yet its result is still compared against a
"boolean" symbol such as TRUE or FALSE.
[color=blue]
> {
> (indented code for the entire rest of the function)
> }
> return somestatusvaria ble;[/color]
Oh, I see. You're complaining against code structure.
[color=blue]
>
> when it should be
>
> if(!foo(bar))
> return NONZEROSTATUSVA LUE;
> (code for the entire rest of the function now not indented so far)[/color]
I prefer:
if(foo(bar))
{
rc = baz();
}
else
{
rc = NONZEROSTATUSVA LUE;
}
return rc;
Do you have a problem with the nesting depth here?
[color=blue]
> (note also that some may have different notions as to what TRUE should be
> defined as: -1, 1 etc. which makes the test against TRUE not just
> idiomatically awkward, but potentially dangerous.)[/color]
Yes, that's what I thought you meant before.
[color=blue]
>
> Even worse is
>
> if(a == b)
> {
> c = TRUE;
> }
> else
> {
> c = FALSE;
> }
>
> which should be
>
> c = a == b;[/color]
This code, whilst correct, will have the newbies (and some older hands)
reaching for their K&Rs. Better: c = (a == b);
[color=blue]
>
>
> or even worse than that
>
> if(a == b)
> {
> c = FALSE;
> }
> else
> {
> c = TRUE;
> }
>
> which should be
>
> c = !(a == b);[/color]
I would prefer c = (a != b);
[color=blue]
> Some of you may be laughing at these last two examples, but don't. I've seen
> it too many times that it's not funny any more.[/color]
I didn't find them particularly funny. Just silly.
<snip>
[color=blue][color=green]
>>
>>Hardly. It's a common style, but its mindshare seems to be diminishing.[/color]
>
>
> I hope its mindshare is dimishing. I would have written the above as:
>
> if (!cap_issubset( inheritable,
> cap_combine(tar get->cap_inheritabl e,
> current->cap_permitted) ))
> goto out;
>[/color]
Mmmm. Well, just pray you never have to maintain my code.
[color=blue]
> This way arguments to functions are lined up.[/color]
Not in my newsreader, they aren't.
[color=blue]
> There's no need for any braces
> at all,[/color]
Well, the compiler doesn't need them. The human sometimes finds them
useful, so I put them in /all/ the time.
[color=blue]
> so leave them out leaving fewer braces to worry about which ones
> match which.[/color]
For a start, they should be close enough together that you can
see which ones match which other ones. And even if they aren't,
if you line them up
{
like this
}
you don't have to worry about which ones match which, because it's
obvious. And even if it weren't obvious, decent modern editors can
whizz you from { to } and back in the blinking of an eye.
<snip>
[color=blue][color=green][color=darkred]
>>>I know almost nothing about the `indent' utility. Can it produce
>>>the spacing above automatically? And suppress it when shorter
>>>names make it unnecessary? I know about `#ifndef lint'; is there
>>>some sort of `#ifndef indent' when one wants to preserve a helpful
>>>white-space arrangement?[/color]
>>
>>The whole point of indent is that you run code through it to
>>convert it to your style, making it easier for you to read.
>>Then, if you need to check it back into CVS, you run the
>>code through it again, this time to convert it to the house
>>style. That way, you don't screw up diff with mere whitespace
>>changes, and everyone's happy. Bye bye holy war.[/color]
>
>
> I do agree with you on that.[/color]
Hallelujah, and amen.
Comment