Systems Programming

Course Coding Standards

To give you a sense of programming on a team and to save my eyesight, this course will follow a defined set of coding standards. Many companies have a house style to ensure coding consistency, and to eliminate unproductive arguments about what are, essentially, arbitrary rules. Because C is a low-level language, it requires substantial discipline to keep complexity in check, and enforcing a good style will help you.

All code you submit (and that you would like me to look at) must conform to our course style.

Of course, all the sound principles of abstraction and modularity apply!

Sign your code

Begin every file you write with a comment block like this:

/*     filename
       by name(s), date
       assignment
 
       summary
 */ 
where filename is the name of the file, name(s) gives the name(s) of the file's author(s), date is the completion date, assignment tells which homework or project assignment this is for, and summary is a brief description of what the code in the file is for and hints about how it works (if that isn't obvious). This should include the relationship to other files where appropriate. For example, a C file might give the name of the include file(s) that clients should use. The block may also include a change log for the benefit of the author(s).

Coding rules

For this course, we will adopt the Linux kernel coding style. These are the rules that govern code that is written for the Linux kernel. Many of you will find the brace placement and/or the indentation will take time to get used to. That's ok (I'm switching, too). Remember, open curly braces at the start of a function go on a line by themselves, but other open curly braces go at the end of the line that opens the block. Follow Linus's conventions!

Use Emacs — it makes it easy

Set Emacs's C Indentation Style to linux. For an idividual editing session, you can type

C-c . linux
It will be easier still if you change your .emacs file to make this apply every time you edit a C file. Here is what I have in my .emacs file, and you should add this to your .emacs file right away:
(setq c-default-style
      '((java-mode . "java") 
        (c-mode . "linux") 
        (other . "gnu"))) 
This will set the indentation depth to 8 spaces and get curly braces to behave.

When you are typing your code and you come to the end of a line, type C-j, rather than a return. If you do this, Emacs indents the next line automatically according to the indentation rules. Alternatively, hitting Tab will indent the current line according to the current rules. If you have edited a function and ruined the indentation (or you fear you may have brace or parenthesis problems), you can indent an entire block by placing the curser over the opening curly brace of the block and typing M-C-q.

Stick to ANSI C

We will use ANSI C, the official standard. This can be difficult since gcc allows many extensions. There are two important restrictions this places on us:
  1. Though gcc allows them, you must use only /* ... */ style comments. Do not use //.
  2. Local variables must be introduced at the start of a block. That means right after the function header (at the start of the function body), or at the start of a group of statements inside curly braces. This one can be very challenging for Java programmers to get used to!

Other rules

Spred thing out

Put spaces around infix operators, such as =, ==, +, *, etc. Also, put a space after every comma in an argument list and after every semi-colon in a for statement. Put a space between the keywords if, for, while and the following parenthesis. Separate curly braces from adacent, non-blank characters. I would like to use my eyes for a few more decades, and you'll find these little things help a lot at 4am. (You would follow these rule if you were writing a paper, and a program is a paper in a formal language written for humans to read.)

Format your code for the worst case

The worst case is the basic 80-column, 24-line terminal screen. So, keep line lengths to 80 columns or less. An easy way to keep track of this is to allow Emacs to have its default size, or at least its default width. Shorter lines are easier to read and ensure that your programs will print nicely (rather than having lots of wrapped or (worse) truncated lines. It also means your code will show up nicely in a default-sized terminal window.

The 24-lines of a default ASCII terminal also help you remember to keep your function short.

Do not yield to temptation

Spreading things out and using large indentations make it difficult to keep to the 80 character line width, and you will be tempted to do bad things. For example, a function body with two nested if if statements will have code indented 24 characters.

Do not violate the indentation rules in order to keep a bunch of code on one line. Breaking lines at appropriate places is good (as long as proper indentation is used). Do not squeeze space out of expressions (e.g., do not remove the spaces around operators, after commas, etc.). The following is bad, very bad:

     int x=2;
   int y=x*a_long_function_name(x*x,atoi(argv[1]),g(x+1,NULL));
 
This is much better:
     int x = 2;
     int y = x * a_long_function_name(x * x,
                                      atoi(argv[1]),
                                      g(x + 1, NULL));
 
You can tell how many arguments this function has even 6 feet from the terminal!

Simple code is better

In order to keep code comprehensible (especially with sparse comments), it is very important to minimize the number of things a reader has to keep in her head at any one time. This leads directly to two important coding conventions:

  1. Use more relatively short functions rather than fewer long functions — in other words, use procedural abstraction extensively.
  2. Keep the complexity of functions down. Do this by structuring your code so that the maximum nesting depth is on the order of 3 (it's hard to keep track of 5 pending conditions or the state of 5 nested loops). Another way to keep code simple is to encode complexity in data structures rather than algorithms whenever possible. Extensive documentation of a static structure definition is easier to understand than code with tons of possible execution paths.



Author: Mark A. Sheldon
Last Modified: 26 January 2008