By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,827 Members | 2,155 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,827 IT Pros & Developers. It's quick & easy.

Coding standards

P: n/a
After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative.

Typically I find that coding standards are written by some guy in the
company who has a way of coding that he likes and then tries to force
everybody else to write code the way he likes it, not for any rational
reason, but simply for the subjective way he likes it. I think this is
wrong.
This is particularly irksome when it comes to issues of code layout style
which has very little relevance to the execution of the code or the
readablility and maintenance of the code.

I also think it is wrong for coding standards to try to prevent idiots from
doing stupid things. No matter how stringent some standards are, somebody
stupid is going to find a way to do something stupid to the code. My point
is that instead of making the standard more restrictive on good coders, the
bad coders should be brought up to speed to be able to write good code, not
pandered to by the standard. For example there is the seemingly universal
attitude that fully bracketed
syntax is the way to go (this will stop the idiots). I strongly disagree.
There are many times that leaving out the braces where not necessary makes
for more readable code. It also reduces the maintenance of braces; the fewer
braces the easier it is to keep braces matched up. The problem is that I
think most coders are too lazy to be bothered to know exactly when they need
braces and when they don't. If you don't know, just stick them in everywhere
that it can't hurt. Lots and lots of braces means lots and lots of code to
maintain that doesn't need to be there.

I recently read a standard that prohibited use of the ternary (conditional
?) operator. I find that most C programmers just haven't bothered to learn
how to use it and don't want others to use it, because then they'll have to
figure it out. However I have also found that in most cases where it is
used, it can make the code much clearer even for those who are not
accustomed to its use.

a = (b == c) ? d : e;

Is just as understandable and more maintainable than

if (b==c) {
a = d;
}
else {
a = e;
}

In the first case it is obvious in one line that you are simply assigning a
value to a based on the condition. The use of the if statement makes for a
lot more code that is subject to error in maintenance.

Another issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier exit
from a function then the early exit should be taken. For eample:

int funct( int arg )
{

.....

if (condition) return ERROR;

....

return OK;

is much better than

int funct( int arg )
{
int retval = ERROR;
.....

if ( !condition) {
retval = OK;
(rest of function);
....
} /* end of if ( !condition) */

return retval;

In the first case you've been very clear as to what values are going to be
returned, you've reduced the number of braces involved and you've reduced
the indentation level of the major part of the function. The argument
against this is that there may be some clean up that needs to be done in a
function and this style may lead an idiot to exit the function with out
doing the clean up. My rebuttal is that number one, only a small minority of
functions have the requirement that the clean up be done before exiting the
function. Number two, the clean up should be a separate function anyway that
can be called from anywhere in the parent function and number three you just
can't count on the standard to protect the code from idiots anyway so why
pretend that it does?

A similar issue is this one:

if (condition) {
retval = func(arg );
}

If that condition has to be tested before each function then the condition
should be evaluated by the function instead:

retval = func( arg, condition);

....
int func( int arg, BOOLEAN condition)
{

if (!condition) return OK;

....
}
On the whole I consider less code to be more maintainable than lots of code.
Anywhere I can reduce the lines of code then that makes it easier to
maintain. For example:

if( condition)
{
retval = func( a, b);
}
else
{
retval = func( a, c);
}

if (retval != OK)
{
error_exit_func();
}

a much better way is

if ( !func(a, condition ? b : c ) error_exit_func();
Is there anybody out there who will agree with me on these issues or am I
the lone voice for this type of coding?


Nov 14 '05 #1
Share this Question
Share on Google+
144 Replies


P: n/a
Natt Serrasalmus wrote:
After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative.

Typically I find that coding standards are written by some guy in the
company who has a way of coding that he likes and then tries to force
everybody else to write code the way he likes it, not for any rational
reason, but simply for the subjective way he likes it. I think this is
wrong.
Well, from the rest of your post one could get the impression
that you are just a more self-aware flavour of "this guy".
Your examples show preferences which may be more restrictive
for some programmers than other coding standards.

This is particularly irksome when it comes to issues of code layout style
which has very little relevance to the execution of the code or the
readablility and maintenance of the code.
This is correct. Sooner or later someone will become coding police
more interested in the right use of indentation, white-spaces,
comment styles and so on.
However, having had the dubious pleasure of coding in a group
where people did not care about the "details", I think that coding
rules which can be scribbled down on one piece of paper are the
best way to go. If you use cvs, even stuff like indentation can
be important enough to be put down on said sheet.

I also think it is wrong for coding standards to try to prevent idiots from
doing stupid things. No matter how stringent some standards are, somebody
stupid is going to find a way to do something stupid to the code. My point
is that instead of making the standard more restrictive on good coders, the
bad coders should be brought up to speed to be able to write good code, not
pandered to by the standard. For example there is the seemingly universal
attitude that fully bracketed
syntax is the way to go (this will stop the idiots). I strongly disagree.
There are many times that leaving out the braces where not necessary makes
for more readable code. It also reduces the maintenance of braces; the fewer
braces the easier it is to keep braces matched up. The problem is that I
think most coders are too lazy to be bothered to know exactly when they need
braces and when they don't. If you don't know, just stick them in everywhere
that it can't hurt. Lots and lots of braces means lots and lots of code to
maintain that doesn't need to be there.
If your company does not use editors which can keep up with braces,
then they may be in trouble...
Honestly, even though "full bracing" is unnecessary, this is one of
the rules which depend on the rest of your coding standard. If there
are no rules about indentation and brace placement or related issues,
the belt and braces (no pun intended) method may be safer.

I recently read a standard that prohibited use of the ternary (conditional
?) operator. I find that most C programmers just haven't bothered to learn
how to use it and don't want others to use it, because then they'll have to
figure it out. However I have also found that in most cases where it is
used, it can make the code much clearer even for those who are not
accustomed to its use.

a = (b == c) ? d : e;

Is just as understandable and more maintainable than

if (b==c) {
a = d;
}
else {
a = e;
}

In the first case it is obvious in one line that you are simply assigning a
value to a based on the condition. The use of the if statement makes for a
lot more code that is subject to error in maintenance.
Well, this depends. I would have placed the parentheses differently,
someone else might leave them out, a third might add all sorts of
parentheses.
However, banishing part of the language's operators or keywords is
only advisable in very special cases. I would be very wroth if
"for" and "do" were disallowed.

Another issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier exit
from a function then the early exit should be taken. For eample:

int funct( int arg )
{

....

if (condition) return ERROR;

...

return OK;

is much better than

int funct( int arg )
{
int retval = ERROR;
....

if ( !condition) {
retval = OK;
(rest of function);
...
} /* end of if ( !condition) */

return retval;

In the first case you've been very clear as to what values are going to be
returned, you've reduced the number of braces involved and you've reduced
the indentation level of the major part of the function. The argument
against this is that there may be some clean up that needs to be done in a
function and this style may lead an idiot to exit the function with out
doing the clean up. My rebuttal is that number one, only a small minority of
functions have the requirement that the clean up be done before exiting the
function. Number two, the clean up should be a separate function anyway that
can be called from anywhere in the parent function and number three you just
can't count on the standard to protect the code from idiots anyway so why
pretend that it does?
You are once more only advocating your own views.
Why not formulate a rule which allows only single exit points
for functions containing cleanup code. Whether this is reached
by state variables, goto or splitting the function into three parts
(initialization, work, cleanup) such that the rule only aims at
the actual cleanup routine, can be up to the programmers and
situation.

A similar issue is this one:

if (condition) {
retval = func(arg );
}

If that condition has to be tested before each function then the condition
should be evaluated by the function instead:

retval = func( arg, condition);

...
int func( int arg, BOOLEAN condition)
{

if (!condition) return OK;

...
}
Perfectly valid for this case. But if func already has seven
parameters, then you are probably doing yourself a disservice
by adding another one or two -- people will just get "blind"
with respect to the arguments.
Given your liking for short expressions you might just go for
condition && (retval = func(arg))

On the whole I consider less code to be more maintainable than lots of code.
Anywhere I can reduce the lines of code then that makes it easier to
maintain. For example:

if( condition)
{
retval = func( a, b);
}
else
{
retval = func( a, c);
}

if (retval != OK)
{
error_exit_func();
}

a much better way is

if ( !func(a, condition ? b : c ) error_exit_func();
Apart from the missing closing parenthesis, I think
that is too much. I would at least let the call to
error_exit_func() reside on a second line.

Is there anybody out there who will agree with me on these issues or am I
the lone voice for this type of coding?


Probably you will find some people who will agree with most
you said.

Without knowing the type and complexity of the code, one usually
can cobble together exactly what you proposed: A coding standard
fitted to the tastes of the creators.

I suggest you start from the purpose of the code and the needed
documentation level.
Then add rules like naming conventions for certain types of objects,
unified interfaces (source, destination, size or destination, source,
size or source, size, destination or ...)
If there is still some room on your sheet of paper, state rules
like "code such that it can be read like prose, avoiding inane
comments". Be specific about comment styles.
If there is still room for more rules, have a look at the bugs
which cost most time to find. Enforcing rules which reduce the
number of these bugs are a good idea. If this means that every
new module gets unit tests, so be it.
If there is still room for more rules, you cheated and went for
toilet paper...

Do not go for rules aiming at whatever makes you itch.
Go for the problems.
Reasons for the above order: If clear documentation is required,
bugs are found sooner, and people who invest enough thought
before coding automatically code in a less convoluted way.
Unified interfaces and naming rules save time.
Weeding out the "fit the quota" comments or other bad habits
by general rules is more effective than trying to cover all
positive good comment/bad comment situations.
If there is a pattern of how bugs get into the code breaking
it helps more than arguing about the intricacies of brace
placement. If you cannot find such rules, then you have found
the point in your software where redesign or alternative
solutions are needed...
HTH
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #2

P: n/a
Op Sun, 19 Dec 2004 18:05:06 -0500, schreef Natt Serrasalmus:
After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative.

Typically I find that coding standards are written by some guy in the
company who has a way of coding that he likes and then tries to force
everybody else to write code the way he likes it, not for any rational
reason, but simply for the subjective way he likes it. I think this is
wrong.
i think an arbitrary decision is (often) right.
that's what standards are all about, uniformity.
e.g. i would have liked that processor vendors had made a decision on
endianness, little or big, and everyone would conform to that standard.

maybe in some circumstances the other convention would be more usefull
(?), but the advantage of having one endianness would be _very_ big indeed!

i don't like these coding standard myself, everyone should code the way I
do :-)
if ( !func(a, condition ? b : c ) error_exit_func();

IMHO this is too short. readability is very important. it should be
easy even for novice programmers.
but if novice programmers don't know ( ? : ) they should learn it instead
of prohibiting it in the coding standard

Nov 14 '05 #3

P: n/a
>After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative.
Most coding standards, if applied in the same way as an employee
dress code, would amount to something like "all employees shall
wear a size 6 red dress catalog # AC37626R from Macy's during working
hours" with no exceptions for the men or the pregnant.

Please consider that there are things that are not worth spending
a lot of time standardizing, such as the positioning of braces,
except to agree that outdenting is awful:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: bulrfl filename\n");
}
exit(0);
}

Typically I find that coding standards are written by some guy in the
company who has a way of coding that he likes and then tries to force
everybody else to write code the way he likes it, not for any rational
reason, but simply for the subjective way he likes it. I think this is
wrong.
If you wish to standardize code layout, the best standard I can
think of is "All C code shall be run through GNU indent with the
following options before being checked into the source code control
system." (I really don't care what options you choose, as long as
outdenting is not selected, and I'm pretty sure it's not even
supported. If necessary, select which options are used by coin
flipping). Some source code control systems can even be made to
do this automatically.
This is particularly irksome when it comes to issues of code layout style
which has very little relevance to the execution of the code or the
readablility and maintenance of the code.

I also think it is wrong for coding standards to try to prevent idiots from
doing stupid things. No matter how stringent some standards are, somebody
stupid is going to find a way to do something stupid to the code. My point
is that instead of making the standard more restrictive on good coders, the
bad coders should be brought up to speed to be able to write good code, not
pandered to by the standard. For example there is the seemingly universal
attitude that fully bracketed
syntax is the way to go (this will stop the idiots).
I agree with braces being used even where optional (e.g. in an if) but
not for the reason "this will stop the idiots". I think it makes
it more readable.
I strongly disagree.
There are many times that leaving out the braces where not necessary makes
for more readable code. It also reduces the maintenance of braces; the fewer
braces the easier it is to keep braces matched up.
If by "matched up", you mean indented at the same level, let GNU
indent handle it. If you mean unbalanced, then leaving them out
is not going to help much, as you won't be any more consistent about
leaving both out as putting both in.
The problem is that I
think most coders are too lazy to be bothered to know exactly when they need
braces and when they don't. If you don't know, just stick them in everywhere
that it can't hurt. Lots and lots of braces means lots and lots of code to
maintain that doesn't need to be there.
If braces are "lots and lots of code", I think the code has a lot
more problems than braces.
I recently read a standard that prohibited use of the ternary (conditional
?) operator. I find that most C programmers just haven't bothered to learn
how to use it and don't want others to use it, because then they'll have to
figure it out. However I have also found that in most cases where it is
used, it can make the code much clearer even for those who are not
accustomed to its use.

a = (b == c) ? d : e;

Is just as understandable and more maintainable than

if (b==c) {
a = d;
}
else {
a = e;
}
I especially find it useful in certain debugging situations:

printf("Name: %s Address: %s\n",
(name == NULL) ? "(null)" : name,
(addr == NULL) ? "(null)" : addr );

where the introduction of temporary variables or replicating the
printf() is undesirable. It makes relating the %s and the argument
that's guaranteed not to be NULL easier.

When you've started nesting ?:, though, you've probably gone too far.
In the first case it is obvious in one line that you are simply assigning a
value to a based on the condition. The use of the if statement makes for a
lot more code that is subject to error in maintenance. Another issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier exit
from a function then the early exit should be taken. For eample:
Generally, I agree here, because you end up with deeper-nested
conditionals, and near the end of the function, you have to look
carefully to see what error conditions you don't have to worry
about because you've already checked them.
int funct( int arg )
{

....

if (condition) return ERROR;

...

return OK;

is much better than

int funct( int arg )
{
int retval = ERROR;
....

if ( !condition) {
retval = OK;
(rest of function);
...
} /* end of if ( !condition) */

return retval;

In the first case you've been very clear as to what values are going to be
returned, you've reduced the number of braces involved and you've reduced
the indentation level of the major part of the function. The argument
against this is that there may be some clean up that needs to be done in a
function and this style may lead an idiot to exit the function with out
doing the clean up. My rebuttal is that number one, only a small minority of
functions have the requirement that the clean up be done before exiting the
function. Number two, the clean up should be a separate function anyway that
Cleanup can hardly ever be in a separate function because of all
the local variables involved. It really doesn't make much sense
to define a separate function with arguments of 7 pointers to free
if they were allocated and 2 open FILE *'s to close if they were
open. On the other hand, there is some use for closeifopen() defined
below if you are careful to initialize FILE *'s to NULL and set
them to NULL after closing a file. Now with memory allocation, you
don't need freeifallocated() since free() itself does the same thing.
can be called from anywhere in the parent function and number three you just
can't count on the standard to protect the code from idiots anyway so why
pretend that it does?

A similar issue is this one:

if (condition) {
retval = func(arg );
}

If that condition has to be tested before each function then the condition
should be evaluated by the function instead:

retval = func( arg, condition);
This depends on how the condition and the function are related.
If, for example, func is actually fopen(), and condition is whether
transaction logging is enabled, I can't see combining those into one
function. On the other hand, I can see defining

void closeifopen(FILE *arg)
{
if (arg != NULL)
{
fclose(arg);
}
return;
}

because the condition is related to whether you can successfully
execute the function at all, not some unrelated reason as to
why you might or might not want to execute it.
...
int func( int arg, BOOLEAN condition)
{

if (!condition) return OK;

...
}
On the whole I consider less code to be more maintainable than lots of code.
Anywhere I can reduce the lines of code then that makes it easier to
maintain.
Lines of code are a ridiculous metric, and you shouldn't use it.
A good coding standard will forbid counting lines of code for any
reason. Taking it to the extreme, all consecutive non-preprocessor
statements go on the same line until you hit line length limits.
For example:

if( condition)
{
retval = func( a, b);
}
else
{
retval = func( a, c);
}

if (retval != OK)
{
error_exit_func();
}

a much better way is

if ( !func(a, condition ? b : c ) error_exit_func();
No, I don't agree this is BETTER, and I think translating from the
first case to the second is a BUG. Who said OK is equal to zero?
Oh, yes, you're also missing a ).

But this really sucks:
if(condition){retval=func(a,b);}else{retval=func(a ,c);}if(retval!=OK){error_exit_func();}
Is there anybody out there who will agree with me on these issues or am I
the lone voice for this type of coding?


I'll go along with you as far as translating the first part to
retval = func(a, condition ? b : c);

Gordon L. Burditt
Nov 14 '05 #4

P: n/a
>>After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative.

Pleasing to see a helpful and sensible discussion here without a flurry of
vitriolic comments claiming it to be off-topic (perhaps it's just a matter
of the weekend or timezones).

--
Chris,
Nov 14 '05 #5

P: n/a
Natt Serrasalmus wrote:
After years of operating without any coding standards whatsoever,
the company that I recently started working for has decided that
it might be a good idea to have some. I'm involved in this initiative.

Typically, I find that coding standards are written
by some guy in the company who has a way of coding that he likes
and then tries to force everybody else to write code the way he likes it,
not for any rational reason, but simply for the subjective way he likes it.
Are you that guy?
I think this is wrong.
Yes, but are you that guy?
This is particularly irksome when it comes to issues of code layout style
which has very little relevance to the execution of the code or the
readablility and maintenance of the code.
You need to distinguish between *style* issues
and good programming practice.
I also think [that] it is wrong for coding standards
to try to prevent idiots from doing stupid things.
I don't think it's wrong.
I just don't think it works.
No matter how stringent some standards are,
somebody stupid is going to find a way to do something stupid to the code.
My point is that instead of making the standard more restrictive on good coders,
the bad coders should be brought up to speed to be able to write good code,
not pandered to by the standard.
For example, there is the seemingly universal attitude that fully bracketed
syntax is the way to go (this will stop the idiots). I strongly disagree.
There are many times that leaving out the braces where not necessary makes
for more readable code. It also reduces the maintenance of braces; the fewer
braces the easier it is to keep braces matched up. The problem is that I
think most coders are too lazy to be bothered to know exactly when they need
braces and when they don't. If you don't know, just stick them in everywhere
that it can't hurt. Lots and lots of braces means lots and lots of code to
maintain that doesn't need to be there.

I recently read a standard that prohibited use of the ternary
(conditional ?:) operator. I find that most C programmers
just haven't bothered to learn how to use it and don't want others to use it,
because then they'll have to figure it out. However, I have also found that
in most cases where it is used, it can make the code much clearer
even for those who are not accustomed to its use.

a = (b == c)? d: e;

Is just as understandable and more maintainable than

if (b == c) {
a = d;
}
else {
a = e;
}
It may be the only practical way to initialize a constant

const int a = (b == c)? d: e;
In the first case it is obvious in one line that
you are simply assigning a value to a based on the condition.
The use of the if statement makes for a lot more code
that is subject to error in maintenance.

Another issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier exit
from a function then the early exit should be taken. For eample:

int funct(int arg)
{

....

if (condition) return ERROR;

...

return OK;

is much better than

int funct(int arg)
{
int retval = ERROR;
....

if (!condition) {
retval = OK;
(rest of function);
...
} /* end of if ( !condition) */

return retval;

This is a bit of a "straw man" argument.
The problem is that functions which contain multiple exit points
are extremely difficult to read, understand an maintain.
Suppose, for example, that you need to modify the code
and malloc some temporary storage.
How do you ensure that that storage is free'd
before any of the multiple exits?

Maybe you can write more concise code
with one, two, three or mre return statements.
But where do you draw the line.
The line has been drawn, perhaps somewhat arbitrarily,
at a single point of return --
preferrably at the end of the function.
This simplifies cleanup, for example,
because the thread of execution is guaranteed
to run through any statements such as free
which are placed just before it.
In the first case you've been very clear as to what values are going to be
returned, you've reduced the number of braces involved and you've reduced
the indentation level of the major part of the function. The argument
against this is that there may be some clean up that needs to be done in a
function and this style may lead an idiot to exit the function with out
doing the clean up. My rebuttal is that number one, only a small minority of
functions have the requirement that the clean up be done before exiting the
function. Number two, the clean up should be a separate function anyway that
can be called from anywhere in the parent function
and number three you just can't count on the standard
to protect the code from idiots anyway so why pretend that it does?

A similar issue is this one:

if (condition) {
retval = func(arg);
}

If that condition has to be tested before each function,
then the condition should be evaluated by the function instead:

retval = func(arg, condition);

...
int func(int arg, BOOLEAN condition)
{

if (!condition) return OK;

...
}

On the whole I consider less code to be more maintainable than lots of code.
Anywhere I can reduce the lines of code
then that makes it easier to maintain. For example:

if(condition)
{
retval = func(a, b);
}
else
{
retval = func(a, c);
}

if (retval != OK)
{
error_exit_func();
}

a much better way is

if (!func(a, condition? b: c) error_exit_func();

Is there anybody out there who will agree with me on these issues
or am I the lone voice for this type of coding?


As far a coding style is concerned
that should be left up to each individual programmer.
Any rules regarding the style used for code repositories
can and should be resolved with a code reformatter such as indent

http://www.gnu.org/software/indent/indent.html

From: E. Robert Tisdale
Subject: Tisdale's C and C++ Style Guide
Newsgroups: comp.lang.c, comp.lang.c++
Date: 2003/01/13

Style is a very subjective and personal consideration.
C and C++ programmers develop or adopt a style
in order to make their code easier for themselves
and other programmers to read, understand and maintain.
If you are developing your own style, there are no rules
except that you should try to be consistent.
Otherwise, you should try to adopt a style
with which other C and C++ programmers are comfortable,
familiar or that they will at least recognize.
Personally, I try to use the same punctuation rules
that are used for ordinary (mathematical) typesetting.
Here are my recommendations:

Terminators always follow immediately after an expression

x@ for all @ in {?, :, ,, ;}

and are followed by at least one white space.
Write

x? y: z

instead of

x ? y : z

or

x?y:z

and write

void f(int, int, int); void g(double);

instead of

void f(int,int,int);void g(double);

for example.

There is no space
between some binary operators and their operands

x@y for all @ in {::, ., ->, .*, ->*, *, /, %, &, ^, |}

but there is always a space
between other binary operators and their operands

x @ y for all @ in {+, -, <<, >>;, <, <=, >, >=, ==, !=,
&&, ||, =, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^=}

except when expressions appear as subscripts.
Write

x + y

instead of

x+y
and

x*y

instead of

x * y

for example.
But you may wish to write

A[i+1][j-1]

instead of

A[i + 1][j - 1]

for example to subscript array A.
Most unary prefix operators never have any whitespace
between themselves and their operands

@x for all @ in {::, ++, --, ~, !, -, +, &, *}

but others do

@ x for all @ in {sizeof, new, delete, delete [], throw}

No unary postfix operators

x@ for all @ in {[], (), ++, --}

ever have any whitespace between themselves and their operands.

Use the normal typesetting rules for parentheses (),
square brackets [], angle brackets <> and curly brackets {}.
No space after (, [, < or { and no space before ), ], > or }.
Write

(x)

instead of

( x )

or

(x )

or

( x)

and write

[x]

instead of

[ x ]

or

[x ]

or

[ x]

for example.
There are, of course, exceptions
where extra white space helps to make your code more readable:

double A[2][3] = {{ 1, -1, 0},
{-10, 11, -21}};
Don't give identifiers cryptic, mangled names.
Use ordinary, meaningful words, conventional symbols
or abbreviations with annotations.
Write

double distance, velocity, acceleration, mass, Force;

Force = mass*acceleration;

or

double x; // distance
double v; // velocity
double a; // acceleration
double m; // mass
double F; // force

F = m*a;

for example.

Don't rely on defaults. Make declarations explicit.
Write

int i = 1;

instead of

i = 1;

to declare and initialize integer i and write

class X {
private:
// Representation
int I;
public:
// Constructors
// ...
};

instead of

class X {
// Representation
int I;
public:
// Constructors
// ...
};

to define the private data members of class X for example.
Use indentation to emphasize scope.
Everybody is comfortable with standard indentation:

void f(void)
{
// indent
}

But I indent curly brackets to the scope of the function body:

void f(void)
{
// indent
}

And I include the open curly bracket with the function heading:

void f(void) {
// indent
}

to save a line of code.

I always indent just two spaces at a time and
I place just one statement on each line so that
there is usually room for a comment at the end of each line
beginning in column 33 or 41.

Write

if (condition) {
// statements
}

instead of

if(condition) {
// statements
}

and

while (condition) {
// statements
}

instead of

while(condition) {
// statements
}

to distinguish flow control structures from function calls.

I use

// comment

for comments in C++ and I reserve

/*
a = b;
// comment
b = c;
*/

to comment out code which may include comments.
If you find yourself in an environment
that requires you to conform to style rules with which you are not
comfortable,
consider investing a little time and effort in a program like astyle

Artistic Style
http://astyle.sourceforge.net/

which changes the appearance of C or C++ programs
by inserting or deleting whitespace.

Write

constant == variable

instead of

variable == constant

when comparing a variable to a constant for equality
so that if you write

constant = variable

by mistake, the compiler will detect the error.

I always write

x < y

or

x <= y

instead of

y > x

or

y >= x

when comparing two values so that the expression is true
when the left hand side is to the left of the right hand side
on the real number line.
Nov 14 '05 #6

P: n/a
On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

....
Another issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier exit
from a function then the early exit should be taken. For eample:

int funct(int arg)
{

....

if (condition) return ERROR;

...

return OK;

is much better than

int funct(int arg)
{
int retval = ERROR;
....

if (!condition) {
retval = OK;
(rest of function);
...
} /* end of if ( !condition) */

return retval;

This is a bit of a "straw man" argument.
The problem is that functions which contain multiple exit points
are extremely difficult to read, understand an maintain.


They can also be very easy to read and maintain. The error is in trying to
make this a style issue at all. Sometimes multiple returns are appropriate
sometimes they aren't.
Suppose, for example, that you need to modify the code
and malloc some temporary storage.
How do you ensure that that storage is free'd
before any of the multiple exits?
While this is a real issue there are many functions that are not affected
by it.

....
Write

constant == variable

instead of

variable == constant
I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far better
to write code that is more readable.
when comparing a variable to a constant for equality so that if you
write

constant = variable

by mistake, the compiler will detect the error.

I always write

x < y

or

x <= y

instead of

y > x

or

y >= x

when comparing two values so that the expression is true when the left
hand side is to the left of the right hand side on the real number line.


That doesn't always express the logic naturally, e.g.

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing. Writing x >= min here is
much more natural.

Lawrence
Nov 14 '05 #7

P: n/a
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

Write

constant == variable

instead of

variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?

--
pete
Nov 14 '05 #8

P: n/a
Natt Serrasalmus wrote:
a = (b == c) ? d : e;


You like those parentheses ?

--
pete
Nov 14 '05 #9

P: n/a
Lawrence Kirby wrote:
.... snip ...
looks nasty to me. I'd have to flip the condition operation around
in my minf to feel comfortable with what it is doing. Writing
x >= min here is much more natural.


Do you realize you are arguing with Trollsdale?

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #10

P: n/a
pete wrote:

Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


No, but for me it break up the flow of reading. Not by much, but
breaking the flow for even less than a second is a problem and
increases the effort needed needlessly.

It does not need to be hard to read at all before it is to hard
to read. IOW, that something is only slightly harder to read is
a very strong argument against it.

--
Thomas.

Nov 14 '05 #11

P: n/a

"Thomas Stegen" <th***********@gmail.com> wrote in message
news:32*************@individual.net...
pete wrote:

Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?
No, but for me it break up the flow of reading.


Having made the same transition myself, I can attest it's a mere question of
getting used to it. The benefit of fishing out possibly unwanted assignments
outweighs the effort IMO.
It does not need to be hard to read at all before it is to hard
to read. IOW, that something is only slightly harder to read is
a very strong argument against it.


That's a good point, but can be solved with a little 'getting used to the
idea'.
However, I do not intend to embark on a private little style-war on this
subject.

"de gustibus non est disputandum" as the romans said.
Nov 14 '05 #12

P: n/a
On Mon, 20 Dec 2004 12:15:51 GMT, pete
<pf*****@mindspring.com> wrote:
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

> Write
>
> constant == variable
>
> instead of
>
> variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


Yes. Every time I see it (and I have cow orkers who do it a lot) I read
"1 == x" as "but 1 can never equal x, it's a constant". OK, it can be
understood eventually but it is non-obvious (in English I would never
say "if 10 is the number of cars", for instance) and delays finding
other errors. Since every compiler I have used in the last decade or so
will flag "if (x = 10)" as a potential error I find the "constant ==
variable" syntax unnecessarily confusing.

Chris C
Nov 14 '05 #13

P: n/a
On Mon, 20 Dec 2004 12:17:36 GMT, pete
<pf*****@mindspring.com> wrote:
Natt Serrasalmus wrote:
a = (b == c) ? d : e;


You like those parentheses ?


My preference is to put the whole of the ternary expression within
parentheses, and additional parentheses for the condition only if it
ind/or the expressions are complex. So I'd write:

a = (b == c ? d : e);
a = ((b == c && d > e) ? (f + d*e) : (g + h*j));

I also put parentheses round expressions more complex than a simple
variable or constant (or sometime a simple function call) used in return
statements:

return 1;
return xyz;
return func(3);
return (a == b);
return (fred + bill*joe);

But that's my personal preferences, when working I conform to the local
style even when I dislike it...

Chris C
Nov 14 '05 #14

P: n/a
On Mon, 20 Dec 2004 12:30:54 +0000, CBFalconer wrote:
Lawrence Kirby wrote:

... snip ...

looks nasty to me. I'd have to flip the condition operation around
in my minf to feel comfortable with what it is doing. Writing
x >= min here is much more natural.


Do you realize you are arguing with Trollsdale?


I know who I was replying to, yes. I try to base my responses on the merit
of the article rather than opinion about who posted it. While style issues
are always subjective I don't see any reason to dismiss the post I replied
to as so unreasonable as to ignore it. And of course if something looks
reasonable but is wrong (not a comment on this case) then it should not be
left unchallenged in the newsgroup.

Lawrence

Nov 14 '05 #15

P: n/a

Chris Croughton wrote:
On Mon, 20 Dec 2004 12:17:36 GMT, pete
<pf*****@mindspring.com> wrote:
Natt Serrasalmus wrote:
a = (b == c) ? d : e;
You like those parentheses ?


My preference is to put the whole of the ternary expression within
parentheses, and additional parentheses for the condition only if it
ind/or the expressions are complex. So I'd write:

a = (b == c ? d : e);
a = ((b == c && d > e) ? (f + d*e) : (g + h*j));

I also put parentheses round expressions more complex than a simple
variable or constant (or sometime a simple function call) used in

return statements:

return 1;
return xyz;
return func(3);
return (a == b);
return (fred + bill*joe);

But that's my personal preferences, when working I conform to the local style even when I dislike it...

Chris C


Coding style standards are good for large teams. However, I try
to
make my code readable and with extensive comments so that I can know
what algorithms I had used when I review the code at a much later time
( 6 months or a year later). There are a number of papers recommending
coding styles. I try to abide by them whenever I can.

Bill Hanna

Nov 14 '05 #16

P: n/a
pete <pf*****@mindspring.com> wrote:
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

Write

constant == variable

instead of

variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable


Why, yes. I expect to ask "Is the size of the block 4?", not "Is 4 the
size of the block?".

Richard
Nov 14 '05 #17

P: n/a
Thomas Stegen wrote:
pete wrote:

Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


No, but for me it break up the flow of reading. Not by much, but
breaking the flow for even less than a second is a problem and
increases the effort needed needlessly.

It does not need to be hard to read at all before it is to hard
to read. IOW, that something is only slightly harder to read is
a very strong argument against it.


Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;

although I will readily concede that, in C, replacement of '=='
with '=' will immediately attach special connotations.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #18

P: n/a
On Mon, 20 Dec 2004 12:15:51 +0000, pete wrote:
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

> Write
>
> constant == variable
>
> instead of
>
> variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable


Briefly, yes, because it isn't the natural idiom. The fact is that we read
left to right and even where an operation is commutative like this there
can be associations for what you expect on the left and on the right.
However it isn't as bad as when relational operators are used.

Lawrence

Nov 14 '05 #19

P: n/a
On Mon, 20 Dec 2004 17:07:48 GMT, CBFalconer
<cb********@yahoo.com> wrote:
Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;


The first one is more expected to change, in English. "Is the ship at
its destination?" makes a lot more sense than "Is the destination at the
ship?", although "Is ship 1 at ship 2?" (where both are variable) makes
sense.

I read C code in words, so I will mentally pronounce

if (var == 4)

as "if var is four", the alternative "if four is var" doesn't make much
sense.

Chris C
Nov 14 '05 #20

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chris Croughton wrote:
[snip]
I read C code in words, so I will mentally pronounce

if (var == 4)

as "if var is four", the alternative "if four is var" doesn't make much
sense.


Which just goes to show the inadequacy of trying to express mathematical truths
in common English.

Mathematically, if a is equal to b, then b is equal to a, and thus it is just as
true to say "if four is var" as it is to say "if var is four".
- --
Lew Pitcher
IT Consultant, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFBxxaaagVFX4UWr64RAjd6AKC7YgQDq+92bWGPpKiE4q xB/6Wg3QCgmowV
xngncTKXe2pNjvhRDqkGmPo=
=GX4a
-----END PGP SIGNATURE-----
Nov 14 '05 #21

P: n/a
On Mon, 20 Dec 2004, pete wrote:
Lawrence Kirby wrote:
I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


No. Instead it's possible that it strikes out as unnecessary obfuscation
that uses a mathematical trick just to do things in an atypical way
(perhaps gaining a debatable advantage) thus slowing down the process of
processing the meaning of the source.

To put it in more technical terms, my brain has 7 registers (plus a stack
pointer which is unavailable) and a disproportionately high penalty for
accesses to long-term memory. In order to optimize their use, I can take
advantage of sopisticated data compression algorithms to make more room
for obvious things with a minimal expense for less obvious stuff. (I have
hardware bit extraction functions so the act of (de)compression doesn't
take those resources)

Now, considering that variable==constant is about 10 times more popular
way of putting things than constant==variable, which of them is more
likely to require spilling an extra register causing a pipeline stall
and a tedious recollection of lost context that might result in a yet
another coffee break?
Nov 14 '05 #22

P: n/a
pete <pf*****@mindspring.com> writes:
[...]
Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


Yes, if only briefly.

Of course we all know that (x == 4) and (4 == x) are entirely
equivalent. The difference is in how I process it mentally as I read
it left-to-right.

The expression (x == 4) tells me something about x, presumably
something useful. The expression (4 == x) tells me something about 4,
a topic on which I think I learned all I need to know before I left
elementary school.

The (4 == x) idiom grates on my nerves in a similar way as something
like:

#include <stdio.h>
int main (
void )
{
printf (
"Hello, world\n" )
;
return 0 ;
}

That's an absurdly exaggerated example, but it's the same idea; it's
exactly equivalent to the more legible version, but it takes too long
to figure that out, for no sufficient benefit.

Now if your mind happens to work in such a way that (x == 4) and
(4 == x) are equally legible, that's great (no sarcasm). But mine
doesn't, and that's not going to change. I can deal with it when I
have to, just as I deal with indentation styles that I dislike; I just
find (x == 4) easier to read.

And yes, I know that some people feel that avoiding (x = 4) errors is
a sufficient benefit. I don't.

If it weren't for the issue of accidentally using "=" rather than
"==", would you even consider writing (4 == x) (or 3["hello"])?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #23

P: n/a
In article <41***********@mindspring.com>,
pete <pf*****@mindspring.com> wrote:
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

Write

constant == variable

instead of

variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable


It takes more time, and it is pointless. Considering how much code I
have to _read_ every day, any unnecessary obstacles like that are really
annoying.
Nov 14 '05 #24

P: n/a
Lawrence Kirby wrote:
E. Robert Tisdale wrote:
Write

constant == variable

instead of

variable == constant
I have to say this is a pet [peeve] of mine.
You are significantly compromising the readability of the code
for a limited case that
many compilers will warn about anyway if you ask them to.


I agree. A quality implementation should warn the programmer
whenever an assignment operator appears in a conditional expression.
IMO it is far better to write code that is more readable.
when comparing a variable to a constant for equality so that
if you write

constant = variable

by mistake, the compiler will detect the error.

I always write

x < y

or

x <= y

instead of

y > x

or

y >= x

when comparing two values so that the expression is true when the left
hand side is to the left of the right hand side on the real number line.

That doesn't always express the logic naturally, e.g.

for (x = max; min <= x; --x)

looks nasty to me.
I'd have to flip the condition operation around in my mind
to feel comfortable with what it is doing.
Writing x >= min here is much more natural.


I don't agree with your comments about readability.
I am completely comfortable with my style rules
and your rules now seem unnatural to me.
But that is exactly the advantage
of developing or adopting a consistent coding style.
It narrows the possible patterns so that
any deviation (often an error) stands out.
Your style may bother other programmers
when they begin to read your code but,
if you are consistent, they will quickly become habituated
and should have no trouble reading, understanding
and maintaining your code.
Nov 14 '05 #25

P: n/a
Chris Croughton wrote:
<cb********@yahoo.com> wrote:
Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;


The first one is more expected to change, in English. "Is the
ship at its destination?" makes a lot more sense than "Is the
destination at the ship?", although "Is ship 1 at ship 2?"
(where both are variable) makes sense.


Neither thing especially implies either variablity nor constancy.
The only question being asked is "are they the same" for some
definition of "the same". In some languages this would require
that they reside in the identical place.

I maintain that it is a mistake to read either more or less into an
expression than is actually meant. In this case the meaning is set
by the ISO C standard. Of course you are perfectly free to use it
in the way that makes most sense to you, but please do not imply
that this is the only usage, nor criticize those who set up an
additional bulwark against silly mistakes. Meanwhile I am
attempting to convince you to join that crowd.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #26

P: n/a
CBFalconer wrote:

Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;


"Backwards run sentences until boggles the mind."
-- Dorothy Parker

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #27

P: n/a
CBFalconer wrote:

Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;
Maybe they don't.

although I will readily concede that, in C, replacement of '=='
with '=' will immediately attach special connotations.


I don't know about you, but I am human. And as such I use language
in certain ways to enhance my understanding of many things.

a == b says to me that the important things here is that a is equal to
b, not that b is equal to a. Now, they mean the same thing, but being
human... Maybe you perceive this as a flaw, but hey, I've found a
coping mechanism.

--
Thomas.
Nov 14 '05 #28

P: n/a
On Mon, 20 Dec 2004 13:35:10 -0800, E. Robert Tisdale wrote:

....
That doesn't always express the logic naturally, e.g.

for (x = max; min <= x; --x)

looks nasty to me.
I'd have to flip the condition operation around in my mind
to feel comfortable with what it is doing.
Writing x >= min here is much more natural.
I don't agree with your comments about readability.
I am completely comfortable with my style rules
and your rules now seem unnatural to me.


In which case you've made it more difficult for yourself to read the
majority of C code out there. Also consider that x in the loop above is
the control variable, if you like the subject, of the loop. It is very
natural that in an expression designed specifically to test its value that
it comes first.
But that is exactly the advantage
of developing or adopting a consistent coding style.
That's an argument for using things like #define BEGIN { as long as you
use them "consistently". That's fine if you work in complete isolation,
but if you ever have to read other people's code or expect other people to
read yours then "consistency" has a broader context than personal
programming preferences. It even goes beyong programming languages where
you can leverage people's abilites to parse English and Mathematical
expressions.
It narrows the possible patterns so that
any deviation (often an error) stands out.
Your style may bother other programmers
when they begin to read your code but,
if you are consistent, they will quickly become habituated
and should have no trouble reading, understanding
and maintaining your code.


I agree with the idea of picking a style and using it consistently, but
that doesn't mean that all styles are equal.

Lawrence

Nov 14 '05 #29

P: n/a
"pete" <pf*****@mindspring.com> wrote in message
news:41***********@mindspring.com...
Lawrence Kirby wrote:

On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

Write

constant == variable

instead of

variable == constant


I have to say this is a pet hate of mine. You are significantly
compromising the readability of the code for a limited case that many
compilers will warn about anyway if you ask them to. IMO it is far
better to write code that is more readable.


Is it really possible for someone who can understand
variable == constant
to get lost while trying to read
constant == variable
?


Yes ! Because it goes against natural flow of thinking : you are comparing the
value of x (variable) to some constant A, not the value of constant A to some
variable x. Take for instance the following example :

if (constant == var) {
...
} else
if (some_other_constant == var) {
....
}

the two tests are closely related, as in a switch statement, placing the
constant first breaks that symmetry.

The possibility for == being mistyped as = is almost always caught in practice,
with the proper warning enabled at compilation time, as most of these
comparisions take place in tests where assignments are definitely suspicious.

--
Chqrlie.
Nov 14 '05 #30

P: n/a

"Chris Croughton" <ch***@keristor.net> wrote in message
news:sl******************@ccserver.keris.net...
On Mon, 20 Dec 2004 17:07:48 GMT, CBFalconer
<cb********@yahoo.com> wrote:
Please explain to me how:

thinga == thingb;

carries any different connotations than:

thingb == thinga;


The first one is more expected to change, in English. "Is the ship at
its destination?" makes a lot more sense than "Is the destination at the
ship?", although "Is ship 1 at ship 2?" (where both are variable) makes
sense.

I read C code in words, so I will mentally pronounce

if (var == 4)

as "if var is four", the alternative "if four is var" doesn't make much
sense.


I think your problem is using the word "is".

var == 4

means:

The value of the expression 'var' is equal to
the value of the expression '4'.

That is, it doesn't mean 'var' *is* 4.

Personally I typically write the "var == 4" form, but I don't
have trouble reading it the other way.

This issue seems to come up here from time to time,
I think it's one of those 'non-issues' myself.
-Mike
Nov 14 '05 #31

P: n/a
"Lawrence Kirby" <lk****@netactive.co.uk> wrote in message
news:pa****************************@netactive.co.u k...
On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing. Writing x >= min here is
much more natural.


There is a more compelling reason why this code looks nasty :
The <= operator is more often than not an indication of problems to come !
Here the loop is bogus in these cases :

- x signed int and min = INT_MIN (a contorted counter example ;-)
- x unsigned int or size_t and min = 0 (a very common mistake !)

Downward for loops are a difficult craft indeed.

--
Chqrlie.

Nov 14 '05 #32

P: n/a
Charlie Gordon wrote:
Lawrence Kirby wrote:
E. Robert Tisdale wrote:

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing.
Writing x >= min here is much more natural.

There is a more compelling reason why this code looks nasty:
The <= operator is more often than not an indication of problems to come!
Here the loop is bogus in these cases:

- x signed int and min = INT_MIN (a contorted counter example ;-)
- x unsigned int or size_t and min = 0 (a very common mistake !)

Downward for loops are a difficult craft indeed.


Your example is bogus.
cat main.c #include <stdio.h>
#include <limits.h>

int main(int argc, char* argv[]) {
for (int x = INT_MAX - 1; x <= INT_MAX; ++x)
fprintf(stdout, "x = %d\n", x);
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

x = 2147483646
x = 2147483647
x = -2147483648
x = -2147483647
Nov 14 '05 #33

P: n/a


E. Robert Tisdale wrote:
Charlie Gordon wrote:
Lawrence Kirby wrote:
E. Robert Tisdale wrote:

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing. Writing x >= min here
is much more natural.


There is a more compelling reason why this code looks nasty:
The <= operator is more often than not an indication of problems to come!
Here the loop is bogus in these cases:

- x signed int and min = INT_MIN (a contorted counter example ;-)
- x unsigned int or size_t and min = 0 (a very common mistake !)

Downward for loops are a difficult craft indeed.

Your example is bogus.
> cat main.c

#include <stdio.h>
#include <limits.h>

int main(int argc, char* argv[]) {
for (int x = INT_MAX - 1; x <= INT_MAX; ++x)
fprintf(stdout, "x = %d\n", x);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main

x = 2147483646
x = 2147483647
x = -2147483648
x = -2147483647
.
.
.

It doesn't matter whether the loop increments downward or upward.
You just need to be careful at the limits of the loop variable.


For the newbies: ERT, the poor sod, cannot get it into his skull
that for signed integers, overflow invokes undefined behaviour.
That means:
int x = INT_MAX;
x++;
will not necessarily wrap around to (x == INT_MIN), so the above
construction is not guaranteed to work.
For unsigned integers, if we run out of the range, the new value
is computed by adding or subtracting one more than the maximum
representable value as often as necessary to come back into
the range 0 .. maximum representable value. Example:
unsigned int x = UINT_MAX;
x++;
means that (x == 0).
-Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #34

P: n/a
Michael Mair wrote:
E. Robert Tisdale wrote:
Your example is bogus.
> cat main.c #include <stdio.h>
#include <limits.h>

int main(int argc, char* argv[]) {
for (int x = INT_MAX - 1; x <= INT_MAX; ++x)
fprintf(stdout, "x = %d\n", x);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main

x = 2147483646
x = 2147483647
x = -2147483648
x = -2147483647
.
.
.

It doesn't matter whether the loop increments downward or upward.
You just need to be careful at the limits of the loop variable.


For signed integers, overflow invokes undefined behaviour.
That means:

int x = INT_MAX;
++x;

will not necessarily wrap around to (x == INT_MIN),


I never said that it did.
so the above construction is not guaranteed to work.
The "above construction" was never guaranteed to work.
But it is guaranteed to fail.
For unsigned integers, if we run out of the range,
the new value is computed by adding or subtracting
one more than the maximum representable value as often as necessary
to come back into the range 0 .. maximum representable value.
Example:

unsigned int x = UINT_MAX;
++x;

means that (x == 0).


So what's your point?

Nov 14 '05 #35

P: n/a
On Wed, 22 Dec 2004 21:13:57 +0100, Charlie Gordon wrote:
"Lawrence Kirby" <lk****@netactive.co.uk> wrote in message
news:pa****************************@netactive.co.u k...
On Sun, 19 Dec 2004 19:29:55 -0800, E. Robert Tisdale wrote:

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing. Writing x >= min here is
much more natural.
There is a more compelling reason why this code looks nasty :
The <= operator is more often than not an indication of problems to come !


Well, the <= operator is more commonly associated with upwards loops,
which is perhaps another reason why the form of the test above looks
strange. You do have to be careful about off-by-1 errors however.
Here the loop is bogus in these cases :

- x signed int and min = INT_MIN (a contorted counter example ;-)
- x unsigned int or size_t and min = 0 (a very common mistake !)

Downward for loops are a difficult craft indeed.


We know there are issues using unsigned variables around 0 because you are
working close to the boundary, and it is easy to just step over it. But
that doesn't really relate to the style issue being discussed.

Lawrence
Nov 14 '05 #36

P: n/a

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:cq**********@nntp1.jpl.nasa.gov...
Charlie Gordon wrote:
Lawrence Kirby wrote:
E. Robert Tisdale wrote:

for (x = max; min <= x; x--)

looks nasty to me. I'd have to flip the condition operation around in my
minf to feel comfortable with what it is doing.
Writing x >= min here is much more natural.

There is a more compelling reason why this code looks nasty:
The <= operator is more often than not an indication of problems to come!
Here the loop is bogus in these cases:

- x signed int and min = INT_MIN (a contorted counter example ;-)
- x unsigned int or size_t and min = 0 (a very common mistake !)

Downward for loops are a difficult craft indeed.


Your example is bogus.


The example code is yours !
I only showed in what cases the use of <= in your example will lead to errors.
You can turn the example around and make a loop going up with the same issue of
course
Or you could use >= even, that will not cure the problem.
> cat main.c #include <stdio.h>
#include <limits.h>

int main(int argc, char* argv[]) {
for (int x = INT_MAX - 1; x <= INT_MAX; ++x)
fprintf(stdout, "x = %d\n", x);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c


gcc complains about comparing an unsigned number to 0 with >= but not in your
example where the result of the comparison is constant, this is a pity !
especially when looking at the assembly, where it is obvious that gcc detected
the infinite loop and removed all traces of the comparison code :

..globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %eax
andl $-16, %esp
xorl %eax, %eax
call __alloca
call ___main
movl $2147483646, %ebx
.align 4
L6:
pushl %eax
pushl %ebx
pushl $LC0
pushl %ecx
call ___getreent
popl %edx
pushl 8(%eax)
call _fprintf
incl %ebx
addl $16, %esp
jmp L6
.def ___getreent; .scl 2; .type 32; .endef
.def _fprintf; .scl 2; .type 32; .endef

It doesn't matter whether the loop increments downward or upward.
You just need to be careful at the limits of the loop variable.


Yes, and using strict comparisons is a better choice.

--
Chqrlie.

Nov 14 '05 #37

P: n/a
I am using a tool, Crystal REVS for C (www.sgvsarc.com) that provides a
practical solution to code layout style and programming practice
issues.

Crystal REVS provides the best code-formatter and the best flowchart
generator that I have seen. You can set format parameters such
K&R/non-K&R braces, indent size, code/comment widths, spaces
before/after operators etc.
1. Code layout style issues - how about the following scenario:

Let the author/responsible engineer use the code layout style he/she
prefers and thus be more productive.

When you review the code, set the format parameters as per your
preference. You will see the code in the format that you prefer - so
you will be more productive.

2. When you edit, Crystal REVS frees you from low-level editing. As
soon as you complete a statement or a declaration, Crystal REVS
automatically formats it as per the format settings. It lines up
successive declarations and successive assignments. It formats long
expressions as per operator precedence rules.

3. Some engineers like to sprinkle comments before and after every few
statements - it is fine - it works for them. I personally prefer the
comments to be on the right so that I can get an uninterrupted view of
the code sequence. With one command, Crystal REVS shifts the comments
to the right and formats them.
4. If you prefer fully bracketed syntax to help you detect problems,
you can command Crystal REVS to automatically insert the brackets.

5. Whether you have multiple exits or a single exit, with Crystal REVS'
flowcharts, you can understand the code easily.

6. Crystal REVS assists you in adding comments to your code. You can
generate a high-level comment flowchart.

Nov 14 '05 #38

P: n/a
First I want to mention that I have read all the responses in this thread, I
just don't have time to respond to them all. Thanks to those who have
replied. More below:

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:cq**********@nntp1.jpl.nasa.gov...
Natt Serrasalmus wrote:
After years of operating without any coding standards whatsoever,
the company that I recently started working for has decided that
it might be a good idea to have some. I'm involved in this initiative.

Typically, I find that coding standards are written
by some guy in the company who has a way of coding that he likes
and then tries to force everybody else to write code the way he likes it,
not for any rational reason, but simply for the subjective way he likes
it.
Are you that guy?
I think this is wrong.


Yes, but are you that guy?


I'm trying not to be. There are things that I like that I can give objective
reasons for liking. For instance, I don't like K&R brace style. I like for
the braces to be at the same indentation level so it's easy to see which
braces match which. Having said that, I also am not that concerned about it
since the editor I use will show which braces match.
This is particularly irksome when it comes to issues of code layout style
which has very little relevance to the execution of the code or the
readablility and maintenance of the code.
You need to distinguish between *style* issues
and good programming practice.


I think that all programmers blur that distinction. Is it good pragramming
practice to put the braces on the same level to show where they match or is
that just a style issue? Is it good programming practice to use if
statements instead of the ternary operator, or is that style?
I also think [that] it is wrong for coding standards
to try to prevent idiots from doing stupid things.
I don't think it's wrong.
I just don't think it works.


Yet you have advocated it!?!?

<snip>

issue that I have come across is the one way out of a function
issue. I contend that if there are conditions that warrant an earlier
exit from a function then the early exit should be taken. For eample:

int funct(int arg)
{

....

if (condition) return ERROR;

...

return OK;

is much better than

int funct(int arg)
{
int retval = ERROR;
....

if (!condition) {
retval = OK;
(rest of function);
...
} /* end of if ( !condition) */
return retval;


This is a bit of a "straw man" argument.
The problem is that functions which contain multiple exit points
are extremely difficult to read, understand an maintain.


No, not at all. Consider:

int func(arglist)
{
(declarations)
int retval = BADSTATUSVALUE;
void *pointer;

if(condition1)
{
pointer = malloc(SOMESIZE);
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(condition2)
{
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(condition3)
{
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(condition4)
{
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
while(condition5)
{
long_line_that_ should_
be_broken_up_because_it_is_so_long_and_indented;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
retval = GOODSTATUSVALUE;
}
} /* condition4 */
} /* condition3 */
} /* condition2 */
} /* condition1*/

free(pointer);
return retval;
}
I'm sure most of us have seen code similar to the above. Now consider:

int func(arglist)
{
(declarations)
void *pointer;

if(!condition1)
return BADSTATUSVALUE:

pointer = malloc(SOMESIZE);
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(!condition2)
{
free(pointer);
return BADSTATUSVALUE;
}

codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(!condition3)
{
free(pointer);
return BADSTATUSVALUE;
}
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
if(!condition4)
{
free(pointer);
return BADSTATUSVALUE;
}
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
while(condition5)
{
long_code_line_that_doesn't_have_to_be_broken;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
codeline;
}

free(pointer);
return GOODSTATUSVALUE;
}

Now then, this second example is far easier to deal with. The extreme
indentation has been eliminated, the distant brace matching has been
eliminated and the retval variable has been optimized away. This results in
several less things to keep track of. With the less indentation, fewer long
lines need to be broken up.
Suppose, for example, that you need to modify the code
and malloc some temporary storage.
How do you ensure that that storage is free'd
before any of the multiple exits?
Look at the example I've given above. If you were a maintenance programmer
adding another condition that required an early exit, you'd have to be a
complete moron not to realize that the pointer has to be freed before the
early exit. The only justification I can see for the one way out in the
first example is to protect the code from morons. That's something that you
admitted doesn't work.

Maybe you can write more concise code
with one, two, three or mre return statements.
But where do you draw the line.
The line has been drawn, perhaps somewhat arbitrarily,
at a single point of return --
preferrably at the end of the function.
This simplifies cleanup, for example,
because the thread of execution is guaranteed
to run through any statements such as free
which are placed just before it.
The examples I've given have made your point moot.

<snip> As far a coding style is concerned
that should be left up to each individual programmer.
Any rules regarding the style used for code repositories
can and should be resolved with a code reformatter such as indent

http://www.gnu.org/software/indent/indent.html
Funny you (as well as others) should mention a reformatter. I've been an
advocate of this for years. A coder would check out code, do anything they
want to it as far as style is concerned and then when they check it back in,
it is reformatted to the standard. Probably nodoby will be happy with the
results, but it is consistent. Whenever I have mentioned this in the past to
anyone, I get sort of a bemused look and an admission that it might be
interesting, but nobody ever seems to want to do it.

<snip a lot of style stuff that seems to be primarily concerned with the use
of whitespace>
Write

constant == variable

instead of

variable == constant

when comparing a variable to a constant for equality
so that if you write

constant = variable

by mistake, the compiler will detect the error.


It's amazing how much response this recommendation generated. Nobody seems
to like it. What is the sole purpose of this recommendation? It is to
protect the code from morons who can't keep track of the difference between
= and ==. Here is a case where those who responded felt that the risk was
worth the convenience of having the expression written the way they prefer
it. Yet I've had many coders of the same ilk act as if some of my
suggestions were just not worth the risk of the damage that some moron might
do to the code. Here's where it becomes a matter of where you draw the line
and unfortunately it really is subjective.
Incidentally, this rule would be better written as:

rvalue == lvalue

but the coders that need this rule probably haven't figured out the
difference between an rvalue and an lvalue anyway and admittedly the
compiler may not catch the problem for all rvalues.

Nov 14 '05 #39

P: n/a
On 26 Dec 2004 14:23:43 EST, in comp.lang.c , "Natt Serrasalmus"
<Ns**********@characoid.com> wrote:
First I want to mention that I have read all the responses in this thread, I
just don't have time to respond to them all. Thanks to those who have
replied. More below:


Natt, a word of advce. E Robert Tisdale is well-known round here for being
a very inaccurate and misleading poster. Treat his advice with caution.

And don't take my word for this (ERT will undoubtedly reply to suggest that
I'm a troll) but look at responses to his posts via google groups. You'll
see the picture pretty quickly.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 14 '05 #40

P: n/a

Natt Serrasalmus wrote:
... particularly irksome when it comes to issues of code layout style

Let me give my two-cents' worth. I'll start with a question
for the `indent' users.

One almost gets the impression that two guys in adjacent
cubicles run their own customized `indent' whenever sharing
code. If you get a paper printout, do you OCR it and `indent'
the result? I'm not being sarcastic; I just don't understand
the fascinated reliance on `indent.' (Below I mention some
problems `indent' will introduce.)

* * * * * * * * * * * * * * * *

In some ways, treatment of C coding style should be similar
to treatment of English writing style. When the N.Y. Times
hires a new editor, they give him a style guide -- I doubt
if it contains a lot of injunctions against things like
run-on sentences, rather it clarifies whether to leave
double-spaces between sentences, and whether to write
"Mr Jones" or to put a period after Mr.

Thus I found it odd that some suggested indentation and
white-space conventions were not a proper topic for a C style
guide. In English, when two words are separated by a comma,
the comma precedes the space, but the space would precede
a left parenthesis. Someone who insisted on reversing this
would be very irritating. Why should C be any different?

Someone taught me to write better English. "Place commas
inside the close quote," he said, "and don't start sentences
with `But.'" Even though I have a rebellious nature, I happily
adopted the first rule: defying punctuation conventions would
have no purpose. But for blunt emphasis, I still start some
sentences with `But.'

Similarly, in C we always write "if (foo(bar))" without
debating whether "if( foo (bar))" is better a priori.
We might *discourage* the nesting of (x ? y : z) operators
if afraid the code would be maintained by novices, but we
would not *forbid* it.

Because the C language and its programmers are flexible and
forgiving, some people may not realize that C white-space rules
are standardized, but the True Style for Coding C is no secret:
you can look at programming examples from Bill Joy or almost any
of the Great Names. Here's a small fragment, essentially in
True Style, from the Linux kernel:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted))) {
goto out;
}

In addition to showing the proper placement of braces, this example
is interesting because of the way a long expression is broken
into multiple lines, with spacing used to make a nested parameter
list more readable. (I mightn't do it quite like this, but only
because I mostly stick to TAB's for extended spacing.)

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?

Hmmm. When I nest expressions of (x ? y : z), I tend to use
line-breaks and spacing to make the logic easy-to-see.
Maybe that's why the `indent' fans seemed to disparage
such nesting -- in their environment the helpful spacing
will tend to be expunged!

It may seem I'm contradicting myself -- advocating strict
adherence to the True Style, yet condoning multi-line
expressions and other deviations. But a deviation and
its purpose will stand out clearly when the style is
otherwise consistent. Some of you are proud of your
non-True Styles and your consistency within that alien
universe, but this reminds me of a Richard Feynman anecdote.
Feynman invented his own trigonometric notation as a youngster.
He was a great genius and his notation was probably superior,
but he abandoned it as soon as he learned the standard and
realized his formulae were going to be read by others.

* * * * * * * * * * * * * * * *

Well, I'd planned on ranting on and on, but I see the ladies
and gentlemen of the jury are getting tired. As you deliberate,
remember that Simplicity is a premier virtue in programming.
The defendants are accused of making every white-space deviation
a legitimate code-style choice (to paraphrase Rush Limbaugh),
and of requiring me to run `indent' to avoid getting dizzy when
I need to look at their code. Since `indent' will obliterate
any special spacing, as in the above fragment or nested ternarys,
they acknowledge that they don't use spacing creatively.
Unless you find that these perverse ideas are indeed a mode
of Simplicity, you must vote to convict.

James Dow Allen
* * * * * * * * * * * * * * * *

Nov 14 '05 #41

P: n/a
jd*********@yahoo.com wrote:

Similarly, in C we always write "if (foo(bar))" without
debating whether "if( foo (bar))" is better a priori.
Which "we" are you talking about? It doesn't include me.

I write if(foo(bar) != 0)
Because the C language and its programmers are flexible and
forgiving, some people may not realize that C white-space rules
are standardized,
But they are not.
but the True Style for Coding C is no secret:
and no standard, either.
you can look at programming examples from Bill Joy or almost any
of the Great Names. Here's a small fragment, essentially in
True Style, from the Linux kernel:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted))) {
goto out;
}

In addition to showing the proper placement of braces,
Hardly. It's a common style, but its mindshare seems to be diminishing.
this example is interesting because of the way a long expression is broken
into multiple lines, with spacing used to make a nested parameter
list more readable. (I mightn't do it quite like this, but only
because I mostly stick to TAB's for extended spacing.)
Readable? I don't think so. I'd simplify the expression, tidy up
the white space, and fix the flow control. Then, maybe, it would
be readable.
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?


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.
Nov 14 '05 #42

P: n/a
infobahn <in******@btinternet.com> writes:
jd*********@yahoo.com wrote:
Similarly, in C we always write "if (foo(bar))" without
debating whether "if( foo (bar))" is better a priori.


Which "we" are you talking about? It doesn't include me.

I write if(foo(bar) != 0)


And I write `if (foo (bar))', assuming foo() returns a "boolean"
result.

It's nonsense to make statements like jdallen2000's above.
--
"When I have to rely on inadequacy, I prefer it to be my own."
--Richard Heathfield
Nov 14 '05 #43

P: n/a

"infobahn" <in******@btinternet.com> wrote in message
news:cq**********@sparta.btinternet.com...
jd*********@yahoo.com wrote:

Similarly, in C we always write "if (foo(bar))" without
debating whether "if( foo (bar))" is better a priori.
Which "we" are you talking about? It doesn't include me.

I write if(foo(bar) != 0)


I find that form really annoying 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.
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?". By that
idiom then it should be obvious to any C programmer worth their pay that

if(strcmp(string1, string2))

means "Did anything go wrong (not match up) when comparing these two
strings?" (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.)

This form also encourages the early exit from a function:

if(strcmp(string1, string2))
return;

If you doubt me, look at K&R where you can find numerous examples of this
form and the early exit from functions.

This may seem awkward at first, but you get used to it. 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.

A similar form that is particularly annoying is

if(foo(bar) == TRUE) /* where true is a macro defined as some non-zero
value */
{
(indented code for the entire rest of the function)
}
return somestatusvariable;

when it should be

if(!foo(bar))
return NONZEROSTATUSVALUE;
(code for the entire rest of the function now not indented so far)

(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.)

Even worse is

if(a == b)
{
c = TRUE;
}
else
{
c = FALSE;
}

which should be

c = a == b;
or even worse than that

if(a == b)
{
c = FALSE;
}
else
{
c = TRUE;
}

which should be

c = !(a == b);
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.

Because the C language and its programmers are flexible and
forgiving, some people may not realize that C white-space rules
are standardized,


But they are not.
but the True Style for Coding C is no secret:


and no standard, either.
you can look at programming examples from Bill Joy or almost any
of the Great Names. Here's a small fragment, essentially in
True Style, from the Linux kernel:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted))) {
goto out;
}

In addition to showing the proper placement of braces,


Hardly. It's a common style, but its mindshare seems to be diminishing.


I hope its mindshare is dimishing. I would have written the above as:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted)))
goto out;

This way arguments to functions are lined up. There's no need for any braces
at all, so leave them out leaving fewer braces to worry about which ones
match which. The "goto out" statement could probably be a return statement
or a few cleanup statements (freeing pointers?) and a return statement (in
which case then braces would be needed and I'd prefer to see them lined up).


this example
is interesting because of the way a long expression is broken
into multiple lines, with spacing used to make a nested parameter
list more readable. (I mightn't do it quite like this, but only
because I mostly stick to TAB's for extended spacing.)


Readable? I don't think so. I'd simplify the expression, tidy up
the white space, and fix the flow control. Then, maybe, it would
be readable.
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?


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.


I do agree with you on that.
Nov 14 '05 #44

P: n/a
"Natt Serrasalmus" <Ns**********@characoid.com> writes:
"infobahn" <in******@btinternet.com> wrote in message
news:cq**********@sparta.btinternet.com... [...]
Which "we" are you talking about? It doesn't include me.

I write if(foo(bar) != 0)


I find that form really annoying 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.
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?". By that
idiom then it should be obvious to any C programmer worth their pay that

if(strcmp(string1, string2))

means "Did anything go wrong (not match up) when comparing these two
strings?" (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.)


Personally, I don't think of the result of strcmp() as a boolean
value. It's effectively a tri-state value, one of <0, 0, or >0
depending on the result of the comparison. I prefer an explicit
comparison:

if (strcmp(string1, string2) != 0) ...

If the function's name implied that it tests whether the arguments
differ, I might feel differently about it.

YMMV, of course, and any C programmer needs to be able to understand
the use of strcmp() in a condition (though I confess it takes me a
moment of thought).

[...] if(foo(bar) == TRUE) /* where true is a macro defined as some non-zero
value */
{
(indented code for the entire rest of the function)
}
return somestatusvariable;

when it should be

if(!foo(bar))
return NONZEROSTATUSVALUE;
(code for the entire rest of the function now not indented so far)
On this I agree wholeheartedly. Never compare a value to TRUE or
FALSE; if such a comparison makes sense, the value is already a
condition and should be used as one.
(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.)
Yup.

[...] if(a == b)
{
c = FALSE;
}
else
{
c = TRUE;
}

which should be

c = !(a == b);
Or

c = (a != b);

(Yes, I like the parentheses, even though they're not strictly
necessary.)

[...] I hope its mindshare is dimishing. I would have written the above as:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted)))
goto out;
That's indented much too deeply for my taste. Are you using hard tabs
with a non-standard tabstop setting?

I might write:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted)))
....
This way arguments to functions are lined up.

[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #45

P: n/a
Natt Serrasalmus wrote:
"infobahn" <in******@btinternet.com> wrote in message
news:cq**********@sparta.btinternet.com...
jd*********@yahoo.com wrote:
Similarly, in C we always write "if (foo(bar))" without
debating whether "if( foo (bar))" is better a priori.
Which "we" are you talking about? It doesn't include me.

I write if(foo(bar) != 0)

I find that form really annoying


I don't.
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.
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.
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?".
Absolutely. And a boolean variable can only answer one of those
questions, which is why so few of my functions return boolean
variables.
By that
idiom then it should be obvious to any C programmer worth their pay that

if(strcmp(string1, string2))

means "Did anything go wrong (not match up) when comparing these two
strings?"
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).
(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.)
We do, however, care whether the result is negative, zero, or positive.
This form also encourages the early exit from a function:

if(strcmp(string1, string2))
return;
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.
If you doubt me, look at K&R where you can find numerous examples of this
form and the early exit from functions.
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.
This may seem awkward at first, but you get used to it.
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.
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.
Oh, I do that already, and have done for many years.

A similar form that is particularly annoying is

if(foo(bar) == TRUE) /* where true is a macro defined as some non-zero
value */
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.
{
(indented code for the entire rest of the function)
}
return somestatusvariable;
Oh, I see. You're complaining against code structure.

when it should be

if(!foo(bar))
return NONZEROSTATUSVALUE;
(code for the entire rest of the function now not indented so far)
I prefer:

if(foo(bar))
{
rc = baz();
}
else
{
rc = NONZEROSTATUSVALUE;
}
return rc;

Do you have a problem with the nesting depth here?

(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.)
Yes, that's what I thought you meant before.

Even worse is

if(a == b)
{
c = TRUE;
}
else
{
c = FALSE;
}

which should be

c = a == b;
This code, whilst correct, will have the newbies (and some older hands)
reaching for their K&Rs. Better: c = (a == b);


or even worse than that

if(a == b)
{
c = FALSE;
}
else
{
c = TRUE;
}

which should be

c = !(a == b);
I would prefer c = (a != b);

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.
I didn't find them particularly funny. Just silly.

<snip>

Hardly. It's a common style, but its mindshare seems to be diminishing.

I hope its mindshare is dimishing. I would have written the above as:

if (!cap_issubset(inheritable,
cap_combine(target->cap_inheritable,
current->cap_permitted)))
goto out;


Mmmm. Well, just pray you never have to maintain my code.

This way arguments to functions are lined up.
Not in my newsreader, they aren't.

There's no need for any braces
at all,
Well, the compiler doesn't need them. The human sometimes finds them
useful, so I put them in /all/ the time.

so leave them out leaving fewer braces to worry about which ones
match which.


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>
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?


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.

I do agree with you on that.


Hallelujah, and amen.
Nov 14 '05 #46

P: n/a
Natt Serrasalmus wrote:
infobahn wrote:
I write

if(foo(bar) != 0)
I find that form really annoying 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.


Idioms are for idiots!
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?".
That's two questions.
By that idiom then it should be obvious to any C programmer worth their pay that

if (strcmp(string1, string2))

means "Did anything go wrong (not match up) when comparing these two strings?"
Because the result returned by strcmp is not zero
and any non zero result used as a conditional
is [implicitly] converted to true.
(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.)


Unfortunately, the rest of us must write code
that is obvious to C programmers *not* worth their pay
as well as C programmers who are worth their pay.
This means that I write explicit code
rather than relying upon implicit conversions.
I would write:

if (0 != strcmp(string1, string2))

to detect strings which don't match.

It isn't my responsibility to ferret out incompetent programmers.
And I don't think that it helps to make competent programmers
work any harder than necessary to understand my intent.

My advice is, "Don't write code
that relies on competent C programmers to maintain it."
Spell it out if it is possible that
some programmer might misinterpret your intent.
Nov 14 '05 #47

P: n/a
On 29 Dec 2004 21:58:30 EST, "Natt Serrasalmus"
<Ns**********@characoid.com> wrote:
the C idiom that was established with the C standard library.
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?"


But that's just not true, except for the I/O functions. Most others
return some value as a result, not as a diagnostic.

I will write "if (a)" providing 'a' is a boolean. If not, I will write
if (a != 0). If that bothers you, so be it.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #48

P: n/a
In article <cq********@dispatch.concentric.net>,
Natt Serrasalmus <Ns**********@characoid.com> wrote:

a = (b == c) ? d : e;

a = b==c ? d : e;

Groetjes Albert

--

--
Albert van der Horst,Oranjestr 8,3511 RA UTRECHT,THE NETHERLANDS
One man-hour to invent,
One man-week to implement,
One lawyer-year to patent.
Nov 14 '05 #49

P: n/a
In article <cq********@library1.airnews.net>,
Gordon Burditt <go***********@burditt.org> wrote:

When you've started nesting ?:, though, you've probably gone too far.
pc = 1==x? "one" :
2==x? "two" :
3==x? "three" :
4==x? "five" ;

I find this nesting acceptable, even if it goes on indefinitely.
Gordon L. Burditt


Groetjes Albert

--

--
Albert van der Horst,Oranjestr 8,3511 RA UTRECHT,THE NETHERLANDS
One man-hour to invent,
One man-week to implement,
One lawyer-year to patent.
Nov 14 '05 #50

144 Replies

This discussion thread is closed

Replies have been disabled for this discussion.