CIS-3333 C++ Coding Standards

For future CIS-3333 programming assignments, please adhere to the following guidelines. Failure to do so will be penalized:

1.  All programs more than 125 lines must include a properly formatted header file for each source file. Only "xxx.h" header files should be #included into other files.

2.  All functions/methods (except main) must have an appropriate prototype (in the header file, if it exists).

3.  All variable declarations should be at the beginning of their respective method/function block, or if global, at the beginning of the program file, before the functions. Class data members (instance variables) should be placed in the class block in the same order you would list them in a UML class diagram, that is, before the methods.

4.  All variable declarations should be given meaningful names and appropriate explanatory comments, to enable the reader to understand what you intend to use them for. Function/method parameters should similarly include descriptive comments explaining their purpose, valid values, and (for reference or pointer parameters) whether the original data will be modified or preserved unchanged. Do not use underscores at the beginning or end of identifiers nor next to other underscores (that is, multiple underscores) except in #define for system-defined names.

5.  All functions and methods should be fully commented, with meaningful comments for every statement whose purpose is not obvious, and a block comment at the beginning explaining what the purpose of this function/method is, along with any preconditions (what it depends on being true to run correctly) and postconditions (what it promises to be true, given the postconditions). Avoid comments that merely repeat the obvious operation of a statement:

str2 = "Hello"; // put "Hello" into str2  <-- meaningless name, useless comment
findStr = "Hello";  // the first of three values to be searched  <-- better
One comment for every 3-10 lines of significant code is a reasonable ratio, but actual appropriate comment density depends on your style of coding and what each line does. Declarations and complex algorithms need more comments than initializations.

6.  Let the indentation and blank-line structure of your code properly reflect the logical structure, so that the body of a loop is indented within the loop header, and statement lines controlled by an if or switch are indented below the respective conditions. One-line conditionals or loop bodies may be placed on the same line with the controlling condition or header, or indented below, at your option, but lines too long to print as a single line should be split and indented past the code line. Use consistent indentation tab stops (not too big), so that a visual examination of the code readily shows its control structure.

One-line comments (starting with "//") should not wrap around to the next printed line, it upsets the visual indentation and makes it look like a syntax error. Fully delimit ("/*...*/") long comments, or (better) break your comments into multiple lines, each properly marked.

Most C style guides recommend that curly braces line up with the outer containing code (on a line by themselves, respectively before and after the indentation takes effect), but in my own code I tend to eliminate lines containing only one curly brace (which I usually fold back into the previous line). I prefer to read code that does not have excessive (nearly) blank lines, but I will accept either style. Blank lines and/or comments separating logical sections of your code are a good idea.

You should always separate larger structures like classes and methods with at least one blank line. If you have a lot of white space within the structures, it may take more than one blank line between them to visually set them off.

7.  Consistently use array notation where you mean the data to be treated as arrays, and pointer notation where you mean to point only to a single instance of a datum.

8.  Range-check your array accesses, unless you can prove that array bounds fault is impossible given the preconditions. Similarly, write into your method/function call code checks for all parameter values to ensure that they meet the stated preconditions, unless you can prove they already meet them.

9.  Consistently use a Java-like boolean (or bool) type for truth values, int for integers, and char for character (and pseudo-string) types. Although it is not always possible (for example, with strstr()), avoid arithmetic on values not intended to represent actual numbers whenever possible.

Although C++ accepts NULL as equivalent to '\0' and/or (int) 0, you should use these constants in a manner appropriate to their type, that is, NULL when the receiving type wants to see a pointer, '\0' when the receiving type wants to see a char, and 0 when the receiving type wants to see an int.

10.  Do not put assignment statements inside an if-condition or other expression; make them separate statements.

11.  Try to make functions which have side effects (change values outside themselves) return void, so you will not be tempted to put their call inside an expression or if-condition. Similarly, avoid as much as possible auto-increment (++) and auto-decrement (--) inside expressions; it's too easy to get the increment on the wrong side of the expression usage.

12.  Although in C/C++ they are semantically equivalent, you should use for-loops when you are incrementing a control variable for use inside the loop, and while-loops when you are not.

13.  Avoid writing methods and functions longer than one page of code.

14.  Break large programs into multiple files, divided into logical sections, and include a makefile to compile the whole lot.

Revised  2003 December 20