A “Style Guide” is a set of rules intended to promote good programming style.  The idea is not unique to this course, or indeed to university programming courses.   Style guides also exist in the real world, where they have the additional advantage of imposing a degree of uniformity throughout a company’s programs (so making it much easier for one programmer to modify a program written by somebody else).

 

Style guides are not a panacea.  It is perfectly possible to produce programs which conform to the letter of a guide but which are nonetheless hopelessly convoluted (as many students will doubtless prove).  It can safely be said, however, that conforming to the style guide will greatly increase your chances of producing good programs


THE SYSC1102 STYLE GUIDE

 

1. Indent Your Code

 

There is a lot of room for disagreement upon the finer details of “bad” and “good” style.   Some people, for example, think that the “break” statement represents poor practice while others argue that it makes for better programs.  Nobody, however, disputes that proper indenting is the very foundation of good programming style.  Proper indenting never hurts, and it makes programs immeasurably easier to understand.

 

There are a number of indenting styles.  Each has it advantages, it drawbacks, its advocates, and its detractors.   While we insist that you consistently make use of one of these styles, you may use whichever one of them suits you best.

 

Style I  (all squiggly brackets on lines by themselves)

 

if (<condition>)

{

  <statements>

}

else

}

  <statements>

}

 

while (<condition>)

{

  <statements>

}

 

do

{

  <statements>

}

while (<condition>);

 

 


Style II  (all closing squiggly brackets on lines by themselves)

 

if (<condition>) {

  <statements>

}

else }

  <statements>

}

 

 

while (<condition>) {

  <statements>

}

 

do {

  <statements>

}

while (<condition>);

 

Style III  (Compact)

 

if (<condition>) {

  <statements>

} else {

  <statements>

}

 

while (<condition>) {

  <statements>

}

 

do {

  <statements>

} while (<condition>);

 

The “short” forms of the “if” statement and so on are not permitted - you must use a (properly positioned) pair of squiggly brackets even when only a single statement is required.  

Some programmers recommend adding a comment to the closing bracket of each construct (as shown below).  Others, however, argue that this gives a false sense of security because no error will be reported if one gets things wrong (and, for example, puts “end if” at the end of a while).

 

if (<condition>) {

  <statements>

} else {

  <statements>

} // end if

 

It can probably be said that this technique is most useful in the case of large programs in which an “if” or “while” may extend over several pages of code.  Its use in this course is optional.

·        When a series of assignments are being done in a sequence, align the assignment operators vertically, as follows

dayRecord.date        = yesterdaysDate +1;
dayRecord.dayInWeek   = next(dayInWeek);
dayRecord.month       = next(currentMonth);
dayRecord.year        = currentYear;

·        When a sequence of declarations is being done, align the consistent parts, such as const, signed/unsigned, type, name, assignment operator and value; For example:

const unsigned int   SOME_LARGE_NUMBER = 3000000000;
        signed int   aVariable;
const signed short   A_SHORT_NUMBER    = 20000;

 

2. Don’t Use Goto’s

 

In the hands of an expert programmer, goto’s can, from time to time, actually improve a program.  In particular they can be usefully employed to get around the unfortunate fact that C++ does not otherwise support breaking out of nested loops.  In general, however, goto’s tend to lead to muddling thinking and to bad programs (generally known as “spaghetti code”).  The goto is thus prohibited.

 

3. “break”statements

 

All switch-case constructs shall have a "break" statement at the end of each non-empty case.

Rationale:
Missing break statements are a cause for some rather famous and serious software failures (for example -  Fall 1989 it caused the shutdown of the Eastern US AT&T long-distance network for 12 hours). A forgotten break causes the wrong code to be executed and is exceptionally difficult to detect. When one finds a case alternative without a break, one must do a lot of analysis to determine if it was planned that way or is an error.

 

4. Use Meaningful Variable Names

 

There are cases in which terse, single character variable names are in fact appropriate.  Consider, for example, the following code segment, which prints out a message ten times.

 

for (i = 0; i < 10; i++) {

  cout << “Hello world!” << endl;

}

 

In this case absolutely nothing would be gained by replacing “i” with a more “meaningful” name. Indeed using a longer name would probably make the code segment harder rather than easier to understand.   Other examples could be offered.  If the function of a piece of code is to determine the value of “x”, “x” may be a quite reasonable variable name, and “n” is commonly used to represent the size of an array. 

 

In general, however, variable names should be descriptive.  Thus “speed” is much better than “s”, and “population” is superior to “p”.  It is often a good idea to use multiple words (separated by underscores, or with the first letter of each word capitalized) in naming variables.   Thus, for example, one might have “initial_population”, or “sizeOfRoom”.

 

The test of a good variable name is whether or not it conveys the role of the variable to the reader.  While sometimes single character names will pass this test, this can be expected to be the exception rather than the rule.  If all (or most) of your variables have single character names, you can be pretty sure that your program will not be acceptable.

 

 

5. Avoid Magic Numbers

 

A “magic number” is a constant which leaves the reader wondering just what it represents, and where on earth it came from.  Consider, for example, the following statement:

 

angular_position = 57.29578 * (omega / i);

 

While some might recognize the value, its significance (and hence the intent of the statement) is far from clear. The value 57.29578 is a “magic value”.  Magic values are not good style and should be avoided by using named constants as shown below.

 

const double degrees_per_radian = 57.29578;

 

....

angular_position = degrees_per_radian * (omega / i);

 

Not only is the assignment statement now much more self-explanatory, but, if the constant were used in a number of places, there would much less chance of a typing error leading to the use of an incorrect value.

 

While all magic numbers are constants, not all constants are magic numbers.  In the case below, the zero is just that.   The reader knows what it represents, and does not wonder where it came from.  Replacing the “0" with a named constant called “zero” would contribute nothing to the clarity of the program, and would instead just make it wordy.

 

if (speed < 0) { // speed is negative

  cout << “We’re going backwards.” << endl;

}

 

6. Put All Declarations First

 

In C++ it is permissible to intermingle “declarative” statements (the declaration of variables and constants) with what might be called “executable” statements (cin’s, cout’s, assignments, and so on).

 

We strongly recommend, however, that students not mix things up, and instead declare first and execute afterwards   If all declarations are kept together you’ll always know where to look for them, and, more importantly, you’ll avoid playing with fire.  Declaring variables “on the fly” raises a number of issues which can get a bit tricky and which we won’t be covering in this course.  Consider, for example, the following code segment:

 

     int b;

 

...

if (b < 0) {

  int a = 7;

 

} else {

  int a = 9;

}

cout << a << endl;

 

If you can understand why it will result in an error message to the effect that “a” is undefined, you are well ahead of the game and are not the kind of student we’re worried about.  If this makes no sense, on the other hand, you’re well advised to avoid getting in over your head.  Just put all your declarations first and this kind of thing won’t crop up.

 

One somewhat special case is that of declaring a variable within a “for” loop as shown below.

 

 for (int i = 0; i < 10; i++) {

  <statements>

}

 

While some would argue that this represents much better style than declaring “i” at the beginning of the function, it also has the potential to leave beginners very confused.   If one breaks out of the loop, for example, “i” cannot be examined to determine when the break occurred.  This is because, if declared in this fashion, “i” only exists for a long as the loop is being executing.  Again, if this all sounds a bit scary, just don’t take advantage of this language feature.   Declare “i” at the beginning, write the loop as “for (i = 0; ...”, and everything should work as you expect it to.

 

7. Arithmetic operations

Do arithmetic only on objects of the same type. If arithmetic on variables of different types must be done, explicitly cast one to the type of the more general type before performing the operation.

Rationale:
The automatic promotion of types can get you in trouble! Truncation, rounding and division are slightly different depending upon the types used and how they are combined. This can lead to subtle (but possibly serious) errors.

 

8. Enumeration type objects

 

Enumeration type objects  may only be compared with objects of the same type, incremented and decremented
      i.e, addition,  subtraction, comparison with numeric or other enumeration types are forbidden

Rationale:
Enumeration types are not integers, even though their internal representation is the same as integers..It is a fundamental error to compare or do arithmetic on literals that are from different enumerations (eg - comparing SUNDAY and RED), or to compare them with numbers.

 

9. increment/decrement operators

Do not use "++" or "--" in complex statements - i.e., only use as the single instruction in a statement, for example

x++;                  //OK
y = name_array[x++];  //Avoid!!!

Rationale:
Code that uses these forms is tricky and difficult to decipher, especially for non-C++ experts. Often the variable which is desired to be incremented (or decremented) is used more than once in the same expression. In such cases it is undefined by the language in which order the increment and the other uses of the variable occur. Code that uses such mechanisms is unportable and often unpredictable.

 

10. Comments

Comments - must not repeat the code, only explain the algorithm