|
|
|
Writing Bug-Free C Code
A Programming Style That Automatically Detects Bugs in C Code
by Jerry Jongerius / January 1995
|
|
|
|
Chapter 8: Style Guide
Writing a style guide is hard because every programmer has his or her
own way of doing things. Despite this problem, I feel that it is
important that a style guide exist in written form at any
organization. The rest of this chapter describes the style that I
use to write code.
8.1 Commenting Code
Every module and every function has a comment header. The layout of
a module is covered in Chapter 6.
Within a function there are two basic forms of comments that I use.
They are the Endline comment and the Inline comment.
8.1.1 Endline Comments
Endline comments are used almost exclusively to document variable
declarations. These declarations can be auto variable definitions
or structure member declarations.
An endline comment uses the C++ style single line comment // (two
slashes) and begins in column 41.
EndLine comment examples, using C++ //
typedef struct {
int x; // the x coordinate of the point
int y; // the y coordinate of the point
} POINT;
int main(void)
{
int nCpuBusy; // how busy is the cpu
(code body)
return 0;
}
|
If you do not have access to a C++ compiler, use the standard C /* */
comment form as follows.
EndLine comment examples, using /* */
typedef struct {
int x; /* the x coordinate of the point */
int y; /* the y coordinate of the point */
} POINT;
int main(void)
{
int nCpuBusy; /* how busy is the cpu */
(code body)
return 0;
}
|
8.1.2 Inline Comments
The inline comment is used to comment a small section of code within
a function.
Inline comment example
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
static char buffer[9000]; /* buffer for input line */
long lLineCount=0; /* number of lines read */
/*--- Count the number of lines in the input ---*/
while (safegets(buffer,sizeof(buffer))) {
++lLineCount;
}
/*--- Display the total line count ---*/
printf( "Number of Lines = %ld\n", lLineCount );
return 0;
} /* main */
|
The inline comment starts with /*--- and ends with ---*/ and always
has one blank line preceding it.
A technique that I use when writing the inline comments of a function
is to pretend that all the code in the function has been removed.
Would reading the remaining inline comments be helpful and
meaningful? Try to write the inline comments so that they would
make sense in this context.
8.2 Indentation Rules/Examples
All of my indentation levels are based on four spaces. So the first
indentation level starts in column 5, the next indentation level
starts in column 9, and so on.
8.2.1 Functions
A function must always consist of a comment header followed by a
blank line and the function body.
Function template
/*pf--------------------------------------------------------------
*
* DESCRIPTION: (Short Description) programmers-initials
*
* (A long description of the function)
*
* ARGUMENTS:
*
* Arg1 - Arg1 description
* ...
* ArgN - ArgN description
*
* RETURNS:
*
* (A description of the return value)
*
* NOTES:
*
* (optional notes section)
*
*--------------------------------------------------------------*/
type APIENTRY FunctionName( arguments )
{
type variable1; /* Comment */
type variable2; /* Comment */
/*--- Comment ---*/
(block of code)
/*--- Comment ---*/
(block of code)
...
} /* FunctionName */
|
The begin and end brace of a function are on separate lines in column
1. In addition, the ending brace is followed by a space and a
comment that is the function name.
Local variable declarations and the main code in the function are at
the first indentation level. The local variables of the function,
if any, are declared first and always have endline comments.
The code within the function uses inline comments to document the
code and follows the blank line before an inline comment rule.
There is always one blank line after the last line of code and
before the ending brace of the function.
8.2.2 The IF Statement
The if statement begins with one line containing the if statement,
the expression and the begin brace. There is one space after the if
statement and before the begin brace. The body of the if statement
and the ending brace are at the next indentation level.
if statement template
/*--- Comment ---*/
if (expression) {
statement;
...
}
|
The if statement always has a begin brace and and end brace, even
when followed by only a single statement.
8.2.3 The IF/ELSE Statement
The if statement begins with one line containing the if statement,
the expression and the begin brace. There is one space after the if
statement and before the begin brace. The body of the if statement
and the ending brace are at the next indentation level.
The else statement begins at the same indentation level as the if
statement and is followed by a space and a begin brace. The body of
the else statement and the ending brace are at the next indentation
level.
if/else statement template
/*--- Comment ---*/
if (expression) {
statement;
...
}
/*--- Else comment ---*/
else {
statement;
...
}
|
The if statement and the else statement always have a begin brace and
and end brace.
8.2.4 The WHILE Statement
The while statement begins with one line containing the while
statement, the expression and the begin brace. There is one space
after the while statement and before the begin brace. The body of
the while statement and the ending brace are at the next indentation
level.
while statement template
/*--- Comment ---*/
while (expression) {
statement;
...
}
|
The while statement always has a begin brace and an end brace.
8.2.5 The DO/WHILE Statement
The do statement begins with one line containing the do statement, a
space and the begin brace. The rest of the do/while statement is at
the next indentation level. The do/while ends with an end brace,
the while statement and the expression on one line. There is one
space after the ending brace and after the while statement.
do statement template
/*--- Comment ---*/
do {
statement;
...
} while (expression);
|
8.2.6 The FOR Statement
The for statement begins with one line containing the for statement,
the three expressions and the begin brace. There is one space after
the for statement and before the begin brace. The three expressions
are contained in parentheses and are separated by a semicolon and
space.
for statement template
/*--- Comment ---*/
for (loop=0; loop<nMax; ++loop) {
statement;
...
}
|
The for statement always has a begin brace and an end brace.
8.2.7 The SWITCH Statement
The switch statement begins with one line containing the switch
statement, the expression and the begin brace. The body of the
switch statement and the ending brace are at the next indentation
level.
The body of the switch statement contains case statements and a
default statement. Each case and default are on a new line with the
body of each case and optional default at a new indentation level.
switch statement template
/*--- Comment ---*/
switch (expression) {
case constant:
statement;
...
break;
case constant: {
statement;
...
break;
}
default:
statement;
...
break;
}
|
If a case uses local variables, begin and end braces are used. The
begin brace is on the same line as the case and begins after the
colon followed by a space. The end brace is on a new line after the
break at the same indentation level as the body of the case.
8.3 Defining Auto Variables
Auto variables should be defined one per line. Do not use the comma
to define multiple variables per line. Consider the following.
Bad use of comma in auto variable definition
void Testing( void )
{
char *pBeg, pEnd; /* comment */
...
} /* Testing */
Correct way to define auto variables
void Testing( void )
{
char *pBeg; /* comment */
char *pEnd; /* comment */
...
} /* Testing */
|
The problem with this code is that the data type of pBeg is char* and
the data type of pEnd is char, which is more than likely not what
was intended. The preferred way to define auto variables is one per
line.
8.4 Avoid Using the Comma Operator
The comma operator is typically used to treat two expressions as one.
This can be useful in situations where only one expression is
allowed. The value of the two expressions separated by the comma
operator is the value of the second expression.
Comma operator syntax
expression, expression
|
However, using the comma operator can lead to code that is hard to
read and maintain. It is best to avoid using it.
One possible exception is in macros where it is important that the
macro be viewed by the programmer as a single expression. If you
cannot accomplish everything in one expression, do you give up? In
cases like this, it is important to avoid having to change the
syntax of how a macro is used and usage of the comma operator is
allowed.
Copyright © 1993-1995, 2002-2008 Jerry Jongerius
This book was previously published by Person Education, Inc.,
formerly known as Prentice Hall. ISBN: 0-13-183898-9
|
|