C/C++ Style Guide
for Use in Computer Science Courses
at Sonoma State University

Version 0.4—January 12, 2023

Introduction

The style guidelines identified in this document represent the default standards for C/C++ programs that are written for courses within the Department of Computer Science at Sonoma State University.

Purpose

Computer programs convey proposed solutions to problems and have at least three audiences:

As a vital mechanism for effective communication, programs must convey solutions clearly and concisely, and programs must be easily readable by a broad audience: a programmer, the programmer's team, and future programmers who may need to study, correct, or maintain the code. Google identifies further "Background" and "Goals of the Style Sheet" at the beginning of its C++ Style Guide.

Although the C/C++ Programming Language allows programmers to utilize a wide range of formatting conventions, the programming culture for both C/C++ and Java largely has settled upon several widely-adopted conventions. Although some style elements vary somewhat from one organization to another, several central elements are identified and will form the style manual for use within computer science courses at Sonoma State University (unless otherwise stated by the instructor of a specific course).

Formatting for Code in both Digital and Paper Form

Line length: Ensure that no lines of code are longer than the maximum number of characters; for computer science courses at Sonoma State, this limit is 80 characters due to C/C++'s inherent verbosity. (Note: Oracle suggests 80 characters; Google's limit is 100 characters. Due to past issues with printing, 80 characters seems appropriate here.)

Indentation using spaces: Any block of code enclosed in curly braces should be indented one level deeper than the surrounding code. Choose a reasonable and consistent convention for indentation; generally 3 to 5 spaces is acceptable. We recommend 3 spaces for indentation. Make sure set the "Tab policy" for all projects.

Additional Notes for Indenting:

Use curly braces consistently: Use "Egyptian"-style curly braces in your code in accordance with the C/C++ style guidelines.

  /* Egyptian braces: opening brace on same line, closing brace on own line */
  if (a == b) {
      cout << "these are Egyptian braces";
  } else {
      cout << "hello, world!";
  }

Curly braces around blocks: Although C/C++ permits the elision of curly braces in cases where the body if-statement or loop consists of a single statement, we require that every block (no matter the number of statements) be enclosed inside curly braces on a new line. It is far too easy to make programming errors of this form otherwise:

// NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO  NO
  while (x < 5)
     cout << "Inside block";
     cout << "BUG -- Not inside block!";
// YES   YES   YES   YES   YES   YES   YES   YES   YES   YES   YES  
  while (x < 5) {
     cout << "Inside block";
  }
  cout << "OK -- Not inside block!";

One statement per line: There should be no more than one statement (declaration, assignment, or function call) on any line of your program.

Use vertical whitespace to separate chunks of code: Within a block of code, use vertical whitespace (blank lines) to separate groups of statements. This makes code more readable and clarifies which statements are logically related. Note that if you have to resort to this rule, you should consider breaking your code up into multiple functions instead.

Always put spaces around operators: Every C/C++ operator should have spaces around it (except the dot operator, e.g. method calls c.foo()). Use parentheses to communicate precedence. For example: 5 - (x + 4) * 8

Additional Formatting for Code in Paper Form

Font: Code should utilize a fixed-width font of size at least 12 point size. We recommend Courier font.

Color: All characters should utilize a dark font (e.g., black, dark blue, dark green, dark brown) on a light background (e.g., white or cream). As a reminder, dark backgrounds are wasteful of ink resources, expensive to print, and sometimes streak or bleed together when printed. Thus, dark backgrounds are unacceptable.

Paper: When printing, use only full sheets of clean white paper. Colored paper or paper with other printing on one or both sides is not appropriate.

Naming

Use descriptive names: Names should reflect their use within the context of the program. For example, total and subTotal describe the contents of the variables; foo and bar do not.

Naming variables and methods: Use lowerCamelCase for variable and method names. Single-word variables should be all lowercase; subsequent words should be joined with their first character capitalized. These identifiers should not contain underscores.

Naming classes: Use UpperCamelCase for class names and enum type names. Do not capitalize acronyms within camelCased names; the string "TCP socket ID" should be written TcpSocketId rather than TCPSocketID.

Naming constant and enum values: Values that are constants, including final static variables and enum values, should follow CAPITAL_CASE conventions, in which all-caps words are separated by underscore characters.

Naming files: Follow common conventions for file extensions. In particular, use ".h" for header files, ".c" for C code, ".cpp" for C++ code, and ".tcc" for C++ template files. Although the C Standard does not require specific file extensions and #include statements require explicit inclusion of extensions within file names, numerous editors and some compilers (e.g., gcc) draw inferences from the extensions used.

More descriptive names for larger scopes: Variables that have greater scope should have more descriptive names. It is often preferred to use a short name like i or j for a loop index, but as the scope of an identifier increases, so should the meaningfulness of its name. For example, prefer leftChild over l for a class field.

Commenting

Do not over-comment code: If the function a piece of code is reasonably obvious to experienced C/C++ programmers, then it likely does not need to be commented. Be judicious; if you are unsure, it is often best not to include a redundant comment. If you feel like it is necessary to extensively comment your code, consider how to rewrite it to make it more straightforward.

Comments should describe purpose over implementation: The code itself is a description of an implementation, so it is unnecessary to comment what the code is doing (e.g., x++ does not need a comment like "Increment x"). Instead, describe at a high level the intended use of the piece of code, such as what task the function performs.

At the start of a program file, write program comments to introduce the program. This should include:

Write C function and C++ public method comments: All C functions, all C++ public methods, and all C++ non-trivial private methods, you should include a block comment with the doxygen syntax /** . . . */. This should describe

Comments to clarify logic: Include comments to explain the logic of each section of code within a procedure or method. At a minimum, at least one comment describing logic should be included within any block of 20 lines.

Comments with Control Blocks: every control block should include a “why” comment. Why is this block of code needed? What is the purpose of the condition in the case of a controlled block of code. (if, while, etc).

Do not submit commented-out code: Remove any dead or commented-out code from your source files before submission.

Verbosity

Use a helper variable or method to avoid computing values multiple times: If you find that a particular sequence of computations is being repeated more than twice, you should assign it to a variable and/or abstract it into a helper function which returns the desired value.

Avoid redundant or verbose expressions: Write expressions such as if conditions, while loop guards, and the like in the most succinct and expressive way possible. Especially consider whether a long expression involving multiple || or && operators is easily readable and whether it could be written with fewer or simpler sub-expressions.

Make use of library functions when possible: C/C++ has quite a rich standard library, so you should make use provided functions instead of re-implementing them (unless otherwise directed). Your own implementation will almost always be less efficient, and is less likely to be correct.

Organization

Ordering of class methods and values: Classes should be organized internally according to this order:

  1. Import statements,
  2. Fields,
  3. Constructors, and
  4. Methods

Methods and classes should perform one specific and unique task: Avoid creating a single method or class that "knows too much"; that is, a method or class which serves multiple disjoint purposes or is responsible for too much. Such implementations are often unwieldy and difficult to extend or debug. This is known as the principle of separation of concerns—each class and method should be responsible for one thing and one thing only. Your program should be composed of a group of such classes which cooperate to achieve a goal.

Use extension only to represent "is-a" relationships: If you create a subclass, make sure that the subtype A "is a" version or variant of the supertype B. If it is more appropriately described as a "has-a" relationship, then consider making B a field of A instead.

Acknowledgments

Although the C/C++ Programming Language allows programmers to utilize a wide range of formatting conventions, C/C++ and Java programming cultures largely have settled upon several widely-adopted conventions. Although some style elements vary somewhat from one organization to another, several central elements are identified and will form the style manual for this course.

Five primary sources for this style sheet follow.

created for Java Summer-Fall 2019
revised for C/C++ April 29, 2022
updated for CS at SSU August 14, 2022
Valid HTML 4.01! Valid CSS!