It is expected that all of your programming assignments will conform to the following coding standards. Failing to follow these standards will result in loss of points.
Please let me know about any improvements you can think of for these standards.
We'll be using a web-based program submission form this semester.
Most of the programs that I assign are short enough that it's reasonable to create a single source program. In most cases, I will ask you to do so, since it makes processing the assignment much easier for the grader; if I assign a program that really requires multiple files, we'll discuss the submission procedures when I do it.
You don't need to turn in a hardcopy of a program. We'll be compiling it, testing it, and printing it.
I will provide you with specifications regarding a program's behavior, and may provide you with examples of possible inputs and outputs. I will not provide you with the test data I actually intend to use. Your program should follow these standards exactly - we will frequently use shell scripts to test the programs, and if their inputs and outputs are not in the required formats the scripts will fail.
However: if you are only able to get your program to partially function, print output that will demonstrate what it does right, even if this ends up not being in the specified format. That'll make it easier to assign partial credit. If your program does work completely, though, it should not print any extraneous output.
Unless otherwise stated for a particular assignment, your program will be tested with the Linux systems in the CS domain. It doesn't matter if it works on your Linux system at home, at CRL, under Windows, under MacOS, or under Solaris. It has to work with our Linux boxes.
Your main() procedure must terminate by returning a
value from main(). Exception: you may
call exit() or abort() for an error
exit; if you call exit(), you must pass it a
non-zero value.
You must #include appropriate header files for all
system and library calls you use. The man pages
for all system and library calls specify the needed header files.
Every function you create must explicitly have a return type (you
may not omit the return type to have it implicitly return an
int). Note that it OK to declare a function as
having a void return type (in which case it does
not actually return anything, so it acts like a procedure).
Any functions you create which return a type other than
void must always in fact return a value (you especially
may not omit the return type so it implicitly returns
int, and then ignore the value returned as if it were a
void - if you do this, it's easy to make a mistake
and use the return value from the function. If you do, you'll
end up using a value that is determined solely by the compiler
implementation, rather than anything useful).
The return values of all non-void system functions must
checked. If an error occurs, it must be reported. If a function
(including system calls) is documented as setting errno
on error, perror() must be used to report it.
Exception: it isn't necessary to check a return from the
printf() family.
Recommendation: compile your code with the -Wall
and -Werror flags enabled. This way, the compiler will
perform extra checking for the sorts of common errors I'm cautioning
against here.
It is very unfortunate that coding standards are frequently called "style" standards, as that tends to give the impression that following them is a matter of taste rather than one of quality. Make no mistake: the standards being described here are necessary to writing good, robust, maintainable code. They are no mere "style" issue.
For instance, the coding standards described here only require that you use a consistent indentation scheme: requiring a particular scheme would indeed be a mere "style" issue. Similarly, these standards require you to use meaningful variable names: requiring a particular naming convention would be "style". You should be aware that in many programming environments these sorts of style constraints could also be required, and enforced.
We expect your program to conform to the following coding standards. Failure to do so will likely result in lost points.
The standard programming languge used in this class is C. You may use C++, but if you do then you must make use of C++'s object-oriented facilities. I've had a few students turn in "C++" programs that were essentially just C programs that used C++'s input and output; this is not acceptable. From our perspective, it combines the worst of both worlds: we can't use a shell script to test it (because the scripts assume C), but it doesn't buy anything in terms of better programming.
Your program must be well-structured. You should make
appropriate use of if, while,
do, switch, and other programming
constructs. If you feel your code would be clearer through the
use of a goto, it almost certainly needs to be
rewritten so the goto is no longer necessary.
Similarly, use of a continue statement is evidence
of poor program design, as is a break (except within
a switch).
Your program must be indented, and must use a consistent indentation style. I don't require any particular style, though.
Don't use global variables. Especially don't use global variables to communicate between functions; that's what parameters are for (there are occasional circumstances which are exceptions to this rule, notably maintaining state in simulations. I'll tell you when circumstances like that arise).
You must use meaningful variable and function names.
Use functions appropriately. As a general rule of thumb, if you
have a function (including main()) that is longer than
25-30 lines, or if you have a block of code that appears twice in your
program, you probably should be making better use of functions.
Every function must have a comment block describing its purpose, parameters, and (if applicable) return values.
In addition to the comment blocks in the previous paragraph,
comments should be used appropriately to describe blocks of code.
Comments should describe what a block of code does; they should
not paraphrase the code (using the comment /* fork off a
process */ to document a call to fork() is not
useful; using the comment /* create child to handle request
*/ is). A single line of code almost never calls for a comment
(or if it does, it's probably a line of very poorly written
code).
One very important thing is that it can be very, very helpful to include occasional comments (typically but not necessarily above a block of code) describing the current state of the system. Comments like
/* finished reading first item; now look for a digit to start the
second item */
can be extremely useful.
Occasionally students have attempted to develop an assignment on another OS such as Windows, MacOS, or even Solaris, intending to port it to Linux later. This has almost always proved to be a bad idea; differences between the operating environments have typically cropped up which have caused a great deal more work than simply developing under Linux in the first place would have.
A program that doesn't compile or doesn't link (on our systems) is worth 0.
A program's value is determined by how closely it follows the specification, not by how much program text would have to be changed to make it follow the specification. A corollary to this is that a program that meets part of the requirements for an assignment is worth a lot more than a program that simply doesn't work, but could be made to work following a trivial code change.
Some advice: it is important that you make no last-minute changes, and then turn in an assignment without one last compile-and-test. Many students have been badly burned by writing and debugging a program, then adding comments at the last minute and turning it in without retesting. In some cases, the comments have contained syntax errors which have caused the program to fail to compile (see the second point in this section).