Skip to content

Coding Style Guide

Carbon Research Group edited this page Feb 3, 2014 · 1 revision

This document explains how you should write code for the Graphite simulator. By following these guidelines, we ensure that the entire simulator is written in the same style, making collaboration and debugging easier. This information can also be found in the file called STYLE_GUIDELINES in the docs directory in the simulator repository.

Summary

classes, structs

  • UpperCamelCase
  • 1 file for each class

methods

  • lowerCamelCase
  • trivial methods in .h file

fields

  • lowercase_underscore
  • always Private

parameters, local variables

  • lowercase_underscore

constants

  • k_ + UPPERCASE_UNDERSCORE

global variables

  • g_ + lowercase_underscore

typedefs and types

  • UpperCamelCase
  • use length-specific types (e.g., UInt32)

include files

  • ALWAYS use guard defines

comments

  • no side comments
  • do not use /* */ for multi-line comments

formatting

  • use Allman (aka ANSI) style for braces and indentation
  • use 3 spaces for each indentation level (NO tabs)
  • prefer lines < 80 characters, NO lines > 120 characters

Detailed Instructions

general naming guidelines

  1. these rules apply to names used for all classes, structs, methods, fields, variables, constants, etc.
  2. keep names short but descriptive
  3. preferably two or three words
  4. most should be less than 18 characters total, NO names over 30 characters

classes and structs

  1. names are all lower case, except for the first letters of each word, which are capitalized (i.e., "UpperCamelCase")
  2. words are not separated by underscores
  3. each major class is stored in its own file, which has exactly the same name as the class
  4. minimize "emergent behavior." in other words, have a clear hierarchy of classes, where the interaction between classes is a tree. If one has to think about the mutual interaction of several classes with the class one is currently writing, then something is probably wrong.

methods

  1. names are all lower case, except any words that are not the first word are capitalized (i.e., "lowerCamelCase")
  2. no underscores
  3. trivial methods (accessors, setters) are placed in the .h file so they can be inlined. functions which are more than 10 lines of code should be placed in the .cc file and not inlined.
  4. list inputs first, then outputs

fields

  1. always ask if this can replaced through use of parameters or local variables. should be used only for state which must be maintained when control-flow leaves the set of methods defined by the class. and even then, attempt to return a value which can be passed in to the next client of the field. this makes the communication and dependence structure of the class more explicit.
  2. names are all lower case, words are separated by underscore (i.e., "lowercase_underscore")
  3. if the variable is only one word, but must be capitalized (e.g., because it is an acronym) a "the_" may be prepended. * Example: UInt32 the_EPC;
  4. all fields should be PRIVATE
  5. if a class contains a field of type MyClass, if there is only one of them instantiated, and its purpose is clear from the class name, then the recommended name is my_class. This saves one the trouble of coming up with a clever name. It also makes it easy to remember what names were assigned to a given field. * For example, the Proc class might define: FetchUnit *fetch_unit;
  6. group elements of equal size together.
  7. group elements that are used most frequently towards the beginning of the structure.

parameters and local variables

  1. lowercase_underscore
  2. if a parameter's purpose is clear from its class name (let's say "MyClass"), its default name is my_class. However, in the case where the parameter is being passed into a "setter" function (in which case there is a field already so named) one should append a "in_", e.g., in_my_class. * Example: MainProc(UInt32 in_imem_size, UInt32 in_dmem_size, DecodeMap *in_decode_map);

constants

  1. UPPERCASE_UNDERSCORE, but names are prepended with "k_", * e.g., k_NUMBER_OF_REGS

global variables

  1. obviously discouraged
  2. sames as local variables, but names are prepended with "g_", * e.g., g_number_of_hits

typedefs and types

  1. typedefs are the same as classes, i.e., UpperCamelCase
  2. use "SInt32", "UInt32", "SInt64", "UInt64", "SInt8", "UInt8" "SInt16", "UInt16" instead of chars, ints or longs
  3. use "int" only for variables which you never store into memory, and which are never intermingled (e.g., added) with elements of the types in (2)

acronyms in names

  1. when an acronym is used in a name, all of the letters in the acronym should have case consistent with the first letter of the acronym. For instance if "SPR" is an acronym: SPRShephard, getSPRShephard(), spr_shephard, g_spr_shephard

include files

  1. do not include "include" files within include files, UNLESS it is a "master" include file which every .cc file includes. this is important because the order of includes affects inlining
  2. protect the text of each include file using guard defines. * For example, in "BufCrossbar.h" use:
   #ifndef BUF_CROSSBAR_H
   #define BUF_CROSSBAR_H
   <text>
   #endif  // BUF_CROSSBAR_H

error conditions

  1. errors should be checked for but not recovered from unless it is relatively easy. Use assert() to check for conditions that should never occur.
  2. avoid sentinels (i.e., a special value for an object that indicates an error). return a boolean to indicate success or failure (presence or absence) instead.

comments

  • in general, don't use "side" comments like this:
stall_reason = blah(&in);    // garner inputs from source

they are annoying to line up, make long lines, and are a hassle to convert to multi-line comments when they get too long. the two places where side comments can be used are variable declarations and reminders on block closings, e.g.,

#define BUF_CROSSBAR_H
   <text>
#endif  // BUF_CROSSBAR_H
  or
  if (foo < bar)
  {
     <very long block>
  } // if (foo < bar)
  • instead use block comments:
  // garner inputs from the ports
  // does not actually dequeue the data,
  // but registers them as candidates for popping
  stall_reason = blah(&in);
  • use // instead of /* and */ for multi-line comments as shown above. /* and */ should be reserved for commenting out large sections of code.
  • do not use
  #if 0
  #endif
  to comment out large sections of code **unless** the code already contains sections commented out using `/*` and `*/`

formatting

  1. use Allman (aka ANSI) style for placement of braces and indentation * opening braces for functions and statements on the next line, by itself, indented to the same level as the function name or statement * contents of block indented one level * closing brace at same level as opening brace
  2. indent using spaces instead of tabs. different people may have their tab-stops set differently leading to messes when tabs and spaces are mixed. configure your editor to insert multiple spaces instead of tabs when you hit the "tab" key.
  3. use 3 spaces for each new level of indentation.
  4. try to keep lines less than 80 characters * no lines longer than 120 characters under any circumstances (shorten your names or break up your strings)