CPS Coding Conventions

Compiler/Environment

Java

We are using Java 1.5.X.

C++

We are using g++ version 3.3.

Indentation Conventions

If you use xemacs, and a .emacs file set up as in ~ola/newuser/.emacs on the acpub system, you should get automatic indenting, matching curly braces inserted automatically, and the BSD-tabbing convention of four spaces per tab stop. The C++ function below shows the indentation and style of braces prefered in CPS courses numbered 108 and below. void Count(istream & input, Vector<int> & counts, int & total) // precondition: input open for reading // counts[k] == 0, 0 <= k < CHAR_MAX // postcondition: counts[k] = # occurrences of character k // total = # alphabetic characters { char ch; while (input.get(ch)) // read a character { if (isalpha(ch)) // is alphabetic (a-z)? { total++; } ch = tolower(ch); // convert to lower case counts[ch]++; // count all characters } }

It's acceptable to include the first curly brace on the same line as the statement that introduces the scope being delimited, but this uses less whitespace and is arguably harder to read. For example:

while (input.get(ch)) { // read a character if (isalpha(ch)) { // is alphabetic (a-z)? total++; } ch = tolower(ch); // convert to lower case counts[ch]++; // count all characters }

In any case, the closing, right curly brace should be aligned with the beginning of the block that it delimits as shown above.


Pre/Post conditions

All functions you write should have pre- and post-conditions that indicate what the function does. If the precondition is true when the function is called, the postcondition will be satisfied when the function finishes. In some cases preconditions are not meaningful, but it's difficult to imagine a function without a postcondition indicating what the function does. All parameters should be documented in the pre/post conditions are in other comments associated with the function header. It's fine to use pre: and post: rather than precondition: and postcondition:

In many situations, functions should have other comments, e.g., that indicate performance characteristics of the function or exceptional situations handled by the function, but outside the scope of the pre/post conditions.


Naming Conventions

All identifiers should be meaningful. The identifiers x and y are meaningful as coordinates, but not for much else (ok, maybe chromosomes too). It's fine to use single letter identifiers for loop control variables, e.g., j and k. Variable identifiers should begin with lower-case letters. Capital letters are used, rather than underscores, to differentiate long names. For example: int count; int numStudents; string firstName; double windchillConversionFactor;

User-defined free functions (that aren't part of a class) should begin with upper-case letters. For example:

double AverageGrade(const Vector<double> & grades, int numGrades);

All private (or protected) class instance variables should have a my prefix, e.g., myCount, myNumStudents. Static class variables should begin with a our prefix, indicating the per-class nature of the variable. For example, a class for a playing card might be partially declared as shown below. This declaration shows the conventions of my/our, it's not, necessarily, meant as an example of a good design.

// includes/declarations here class Card { public: Suit getSuit() const; Rank getRank() const; private: Rank myRank; // the rank of this card Suit mySuit; // the suit of this card Deck * ourDeck; // all cards belong to the same deck };

Class names are capitalized, e.g., Card as shown above. Member function names for user-defined classes should begin with a lower-case letter (except, obviously, for constructors/destructors).


Owen L. Astrachan
Last modified: Wed Aug 16 07:58:08 EDT 2000