CSC 357 Coding Conventions
CSC 357 Coding Conventions
The standards for code submitted in 357 are presented in five categories:
Program Organization and Style
Except for assignment 1, all submitted programs must be organized into pairs of
.c and .h files.
-
The .h contains function declarations, type declarations, and global
constant declarations.
-
The .c contains function definitions.
To guard .h files against multiple inclusion, use the standard
conditional-compilation convention with "ifndef
...". E.g., for a file named X.h:
#ifndef X_included
#define X_included
...
#endif
Additional conventions for organization and style are the following:
-
Use meaningfully-mnemonic names for typedefs, functions, variables, and
constants.
-
Limit function definitions to 50 lines of code or fewer, not including
comments, blank lines, or lines with a single opening or closing curly brace.
-
Avoid "magic numbers". For constants, use either preprocessor defined
constants or const variables, e.g.,
#define TAB_WIDTH 8
...
for ( i = 0 ; i < TAB_WIDTH; i++)
...
or
const int tabsize = 8;
...
for ( i = 0 ; i < tabsize; i++)
...
-
Indent properly. The exact depth of indentation is not important, but it must
be consistent. Remember, however, that if you choose to indent a full tab-stop
(8 spaces) for each level, you'll get very deep very fast.
-
There are several accepted conventions for brace placement. Choose
one and follow it. In all cases, an open brace ("{") is always
the last non-comment or whitespace item on a line, and a close brace ("}") is
always the first.
Three widely-used conventions are the following:
-
Old-style (K&R) This format is dense and very readable, but
sometimes open braces at the end of a line do get lost visually:
if ( cond ) {
/* body */;
}
-
Newer-style This is not quite as dense, but some people find
it is easier to see open braces:
if ( cond )
{
/* body */;
}
-
GNU-style Braces are placed halfway between outer indentation
level and the inner level. A lot of old-school types think it's funny-looking,
but it is the style used for code from the
Free Software Foundation:
if ( cond )
{
/* body */;
}
-
It is a corollary of the above, but avoid constructs that obfuscate control
flow. Some programmers are fond of writing brief conditional statements on one
line like this:
if ( cond ) { thing; };
or, worse yet, this:
if ( cond ) thing;
Do not do this. Not only does it violate the "an open brace is the last thing
on a line" rule (above), but this sort of bracing visually obscures the control
flow of the program making it difficult to read.
-
Break long lines. Your program should have no lines over 80 characters (the
standard terminal width). This is when tabs are expanded to 8-column tabstops.
To check if your source conforms to this convention, run the following program
on falcon/hornet:
~gfisher/bin/longlines.pl
E.g.,
hornet% ~gfisher/bin/longlines.pl foo.c
LINES TOO LONG:
foo.c has 1 lines over 80 characters.
The longest was 106 characters at line 8.
-
Be wary of tabs: Regardless of what you set tab stops to be in your editor,
standard tab stops in the UNIX environment are every eight columns. Be sure
that your indentation and line lengths are ok with standard tab stops.
To check your code with standard tab sizes, simply cat or
more it and see if it looks ok.
Tab characters are so troublesome that many industrial coding styles forbid
their use. You, too, may want to do away with tabs in your code. If your
editor does not support this, look into the UNIX command expand(1).
-
Use modular design for your programs. Functional units of your program should
be implemented as independent functions. If you find yourself duplicating a
lot of code, you should put it in a function and reuse it with function calls.
-
Make data-flow explicit. That is, functions should communicate via their
parameters and return values, not through global variables.
Functionality
Assignment writeups will have "black box" specifications for functionality.
These specs must always be met.
In general, your programs should handle error conditions gracefully. That is,
you must validate your inputs and check the return values from library and
system calls for success. In case of failure, you must print an error message
indicating the reason and exit with a non-zero status.
Compilation
For the greatest level of portability and reliability, it is important to stick
to the most standard features of the C language. To that end, all programs
submitted must compile cleanly with the gcc options "-Wall" (all
warnings) and "-ansi" (follow ANSI standards).
Passing -Wall not only helps with portability, but also with
correctness. For even greater assistance from the compiler, you can turn on
the optimizer, with -O. The optimizer performs dataflow analysis and
can detect some ininitialized variables. Note that the use of -O
precludes the use of the -g debugging flag, so you'll not use
-O to run your program under gdb.
In general, you should choose more common language features over more exotic
ones. The -ansi option helps in this regard. For example, on-the-fly
declaration of variables (in the manner of C++ or Java) is supported by the ISO
C99 standard. However, many deployed compilers only conform to the ANSI C89
standard, which requires variables to be declared at the start of a block.
While it is sometimes convenient to declare a variable on the run, it is much
more likely to be portable to make all your declarations at the top of a block.
Documentation
-
Each .h file must have a top-level comment that describes the
functionality of the program module defined in a .h/.c file
pair. The comment must include the following information:
-
A description of the purpose of the module. The length of the description is
commensurate with the size and complexity of the module. I.e., larger and more
complex modules require lengthier descriptions.
-
A summary of the functions provided.
-
A summary of the types defined.
-
Each typedef declaration in a .h file must be preceded with a comment
describing the data representation of the type and what it is used for.
-
Each function declaration in a .h file must be preceded with a comment
that describes the external function behavior. This is a description of what
the function does, not how it is implemented. Describe the use of each
parameter by name, and describe the function output. Also describe any
modifications made to call-by-reference parameters. Stylistically, use
complete sentences, avoid passive voice.
-
The function comment need not be repeated above the definition in the
.C file, but you may do so if you like.
-
Within the body of a function definition, each local variable must have at
least a brief comment describing its use.
-
Any non-trivial code within the body of the function should be commented.
There are no specific conventions for how much of this commentary you must
provide. However, if a submitted program is not fully functional and you would
like it considered for partial credit, you must comment the code.
-
Use C-Style (/* ... */) comments. While many C compilers support the C++ (and
Java) style comments (// ...), they are not part of the C language and are not
portable.
-
Starting with programming assignment 3, all header, typedef, and
function declarations must be doxygen compliant. This convention will be
expanded upon in a future addendum to this document.
Scoring
Scoring of 357 programs will be based on execution results and adherence to
coding conventions. Points for program execution are defined in the test plan
for each program, on a 100-point scale.
After the execution score is determined for a program, points are deducted for
any violations of the conventions specified in this handout. The following are
the specific deductions:
-
-8 points for each uncommented .h file, up to a total of -20 points
-
-4 points for each uncommented function, up to a total of -20 points
-
-3 points for each function longer than 50 lines, up to a total of -12 points
-
-3 points for each uncommented typedef, up to a total of -12 points
-
-1 point for each uncommented local variable, up to a total of -8 points
-
-5 points for each .c file without a companion .h file, up to
a total of -12 points (does not apply to Program 1)
-
-2 points for each egregious violation of any other coding convention defined
above, up to total of of -10 points.
The total maximum deduction for convention violations is 35 points out of 100.
If deductions from the specific categories above add up to more than 35 points,
the total deduction will be limited to 35 points overall.
index
|
lectures
|
labs
|
programs
|
handouts
|
solutions
|
examples
|
documentation
|
bin