593 lines
18 KiB
TeX
593 lines
18 KiB
TeX
\documentclass[11pt]{article}
|
|
\usepackage{times}
|
|
\setlength{\textwidth}{6.5in}
|
|
\setlength{\textheight}{9in}
|
|
\setlength{\oddsidemargin}{0.0in}
|
|
\setlength{\evensidemargin}{0.0in}
|
|
\setlength{\topmargin}{-0.5in}
|
|
\def\nst{{\em ns--3}}
|
|
\newcommand{\code}[1]{\texttt{#1}}
|
|
|
|
\begin{document}
|
|
\begin{center}
|
|
{\Large Coding Standard for ns--3}\\
|
|
August 22, 2005
|
|
|
|
\end{center}
|
|
\section{Introduction}
|
|
|
|
The purpose of the \nst\ project is to build software which will last
|
|
many years: making sure that the code is readable and stays so is
|
|
one of the most important items required to achieve this goal. This
|
|
document thus outlines guidelines we plan to enforce on each component
|
|
integrated in \nst to ensure uniformity of the codebase which is
|
|
a first step towards readable code.
|
|
|
|
\section{Recommendations}
|
|
|
|
The following recommendations are not strict rules and some of them
|
|
are conflicting but the point here is to outline the fact that we
|
|
value more common-sense than strict adherence to the coding style
|
|
defined in this document.
|
|
|
|
\subsection{naming}
|
|
|
|
Types, methods, functions and variable names should be self-descriptive.
|
|
Avoid using acronyms, expand them, do not hesitate to use long names,
|
|
Avoid shortcuts such as \code{sz} for \code{size}. Long names sometimes get in the
|
|
way of being able to read the code:
|
|
\begin{verbatim}
|
|
for (int loopCount = 0; loopCount < max; loopCount++)
|
|
{
|
|
// code
|
|
}
|
|
\end{verbatim}
|
|
loopCount should be renamed to something shorter such as
|
|
\code{i}, \code{j}, \code{k}, \code{l}, \code{m}, and \code{n}
|
|
which are widely used names which identify loop counters:
|
|
\begin{verbatim}
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
// code
|
|
}
|
|
\end{verbatim}
|
|
Similarly, \code{tmp} is a common way to denote temporary variables. On
|
|
the other hand, \code{foo} is not an appropriate name: it says nothing
|
|
about the purpose of the variable.
|
|
|
|
If you use predicates (that is, functions, variables or methods
|
|
which return a single boolean value), prefix the
|
|
name with \code{is} or \code{has}.
|
|
|
|
\subsection{Memory management}
|
|
|
|
As much as possible, try to pass around objects
|
|
by value and allocate them on the stack. If you need to allocate
|
|
objects on the heap with new, make sure that the corresponding
|
|
call to delete happens where the new took place. i.e., avoid
|
|
passing around pointer ownership.
|
|
Avoid the use of reference counting and, more generaly, strive to
|
|
keep the memory-management model simple.
|
|
|
|
\subsection{Templates}
|
|
|
|
For now, templates are defined only in the simulator
|
|
core and are used everywhere else. Try to keep it that way by
|
|
avoiding defining new templates in model-specific code.
|
|
|
|
|
|
\section{Standards}
|
|
\subsection{General}
|
|
\begin{enumerate}
|
|
\item There will be no {\em tab} characters in the code. Rather, repeated
|
|
spaces are used to separate the characters as needed.
|
|
\item No line of code will be longer than 80 characters in length, to
|
|
prevent lines wrapping in the {\tt emacs} or {\tt vi} editors. For both
|
|
of these linux text editing tools, the default is a window that is
|
|
exactly 80 characters wide, so if none of the lines wrap when editing
|
|
in {\tt emacs} or {\tt vi} this requirement is met.
|
|
|
|
\item Each C++ statement will be on a separate line. The only exception
|
|
is when an {\tt if}, {\tt else}, {\tt for} or {\tt while}
|
|
statement has a single
|
|
statement sub--block these can be on the same line.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
int i = 0; // Right\\
|
|
i = 10; j = 20; // Wrong. Two statements same line\\
|
|
Sub1(k); Sub2(k); // Wrong. Two statements same line\\
|
|
if (done) break; // Right. If statement with single statement sub-block
|
|
\end{tt}
|
|
|
|
\item Each variable declaration will be on a separate line.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
int c, d; \=// Wrong. c and d defined on same line.\\
|
|
int a = 0; \\
|
|
int b = 0; \>// Right. a and b on different lines\\
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item Variables should be declared at the point in the code
|
|
where they are needed, and should be assigned an initial value
|
|
at the time of declaration.
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
int a = 0; \=// Right, a is assigned in initial value.\\
|
|
int b; \> Wrong, b is not assigned an initial value.\\
|
|
int c = 0; \\
|
|
int d = Sub1(a, b);\\
|
|
c = Sub2(d); \> // Wrong, c should be declared here, not above
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item Excepting when used in a {\tt switch} statement, the open
|
|
and close curly braces (\{ and \}) are always on a separate line.
|
|
|
|
Examples:
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
for (int i = 0; i < MAX\_COUNT; ++i) \\
|
|
\>\{ // Right. Open brace on separate line \\
|
|
\>\>sum += i; \\
|
|
\>\>prod *= i; \\
|
|
\>\} // Right. Close brace on separate line
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
for (int i = 0; i < 10; ++i) \{ // Wrong. Open brace on same line\\
|
|
\>sum += i; \\
|
|
\>prod *= i; \} // Wrong. Close brace on same line
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item The C++ {\tt goto} statement is not to be used.
|
|
\end{enumerate}
|
|
\subsection{Commenting}
|
|
In general, comments should be use liberally throughout the program to
|
|
increase readability. Specifically:
|
|
|
|
\begin{enumerate}
|
|
\item C++ style comments using the {\tt //} delimeter
|
|
are to be used, rather than C style comments with the {\tt /*}
|
|
and {\tt */} delimieters.
|
|
|
|
\item Variable declaration should have a short, one or two line comment
|
|
describing the purpose of the variable, unless it is a
|
|
local variable whose use is obvious from the context. The short
|
|
comment should be on the same line as the variable declaration, unless it
|
|
is too long, in which case it should be on the preceding lines.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
int averageGrade; // Computed average grade for this project \\
|
|
// Note. The above comment likely qualifies as \\
|
|
// obvious from context, and could be omitted.
|
|
\\
|
|
// Counts the total number of students completing the project, but\\
|
|
// does not include those not turning in the project. \\
|
|
int projectCount = 0;
|
|
\end{tt}
|
|
\item Every function should be preceded by a detailed comment block
|
|
describing what the function does, what the formal parameters are, and
|
|
what the return value is (if any).
|
|
|
|
\item Every class declaration should be preceded by a comment block
|
|
describing what the class is to be used for.
|
|
|
|
\item Unless obvious from context, each {\tt if} statement should
|
|
include a one--line comment on the open curly brace following describing
|
|
the {\tt TRUE} condition and the {\tt FALSE} condition.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
if (iter == students.end()) \\
|
|
\>\{ // Student not found, add him \\
|
|
\>\>students.push\_back(thisStudent); \\
|
|
\>\} \\
|
|
else \\
|
|
\>\{ // Student exists, modify existing data \\
|
|
\>\>iter->grade += thisGrade; \\
|
|
\>\}
|
|
\end{tabbing}
|
|
\end{tt}
|
|
\item Class and function comments should adhere to the Doxygen standard
|
|
format, for automated extraction by the Doxygen tool. {\em Note from
|
|
GFR. We need a bit more here, as Doxygen has several possible methods
|
|
for commenting. I'll look them over and suggest an approach, for later
|
|
discussion}
|
|
|
|
\end{enumerate}
|
|
\subsection{Naming Conventions}
|
|
\begin{enumerate}
|
|
\item {\bf Variable Names}. All variables, including global variables,
|
|
local variables, formal parameters,
|
|
and member variables in classes will start with a
|
|
lower case letter, and consist of only alphabetic characters and numeric
|
|
digits. Capital letters are to be used when appropriate between words
|
|
in a variable name for increased readability.
|
|
Variable names should not contain the underscore character.
|
|
|
|
Examples:
|
|
|
|
{\tt int i;}\\
|
|
{\tt int nextIndexValue;}\\
|
|
{\tt int sum1;}\\
|
|
{\tt int loopCount10;}
|
|
|
|
\item {\bf Class Member and Global Variables}. To be able to distinguish
|
|
local variables from class member and global variables, prepend the
|
|
\code{m\_} prefix to class member variables and the \code{g\_} prefix
|
|
to global variables.
|
|
|
|
Examples:
|
|
\begin{verbatim}
|
|
class Foo {
|
|
private:
|
|
int m_myPrivateVar;
|
|
};
|
|
static int g_myGlobalVar;
|
|
\end{verbatim}
|
|
|
|
\item {\bf Subroutine Names}. All subroutine names, including global
|
|
routines and member functions in classes, will start with an upper case
|
|
letter, and consist of only alphabetic characters and numeric digits
|
|
(although digits should be rarely needed).
|
|
As in variable names, upper case letters are to be used between words as needed
|
|
to increase readability.
|
|
|
|
Examples:
|
|
|
|
{\tt int ComputeNextIterator()}\\
|
|
{\tt int Calculate()}\\
|
|
{\tt int TransmitPacket()}\\
|
|
{\tt int Dummy()}
|
|
|
|
\item {\bf Defined Constants}. All defined constants will be all upper
|
|
case letters or numeric digits, with the underscore character separating
|
|
words.
|
|
|
|
Examples:
|
|
|
|
{\tt typedef enum \{ PACKET\_RX, PACKET\_FIRST\_BIT\_RX, PACKET\_TX\} }\\
|
|
{\tt \#define NUMBER\_ELEMENTS 10}\\
|
|
{\tt const int LOOP\_COUNT = 100}
|
|
|
|
\item {\bf Defined Types}. All user defined types will end start with
|
|
an upper case letter, consist of upper and lower case letters only, and
|
|
end in {\tt \_t}.
|
|
|
|
Examples:
|
|
|
|
{\tt typedef double Time\_t; // Simulation time}\\
|
|
{\tt typedef unsigned long SimulatorUid\_t; // Unique ID for each event}\\
|
|
{\tt typedef unsigned long Event\_t; // Idenifies events in handler}\\
|
|
|
|
\item {\bf Class Names}. Class names will start with an upper case letter,
|
|
consist of only alphabetic characters, and include capital letters as
|
|
needed to increase readability.
|
|
|
|
Examples:
|
|
|
|
{\tt class DropTailQueue \{}\\
|
|
{\tt class Ferrari \{}\\
|
|
|
|
\end{enumerate}
|
|
|
|
%\newpage % Adjust as needed
|
|
\subsection{Statement Formatting}
|
|
\begin{enumerate}
|
|
\item {\bf Indention}. The basic indention level for all code
|
|
is two character positions.
|
|
\item {\bf Continuation statements}. Frequently a single statement
|
|
is too long to fit within a single 80 column line. In this case, the
|
|
statement is simply continued on the next one or more lines. Each
|
|
continuation line must be indented at least one--half indention level,
|
|
and more as necessary to increase readability.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
longVariableName = \=(anotherLongName * shorterName) + (loopIndex2 * i) + \\
|
|
\>(k * j); // Correct, indented for neatness
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
a\=a\=a\= \kill
|
|
for (LongTypeName\_t longLoopIndexName = aLongExpression; \\
|
|
\>longLoopIndexName < MAX\_VALUE; \\
|
|
\>longLoopIndexName++) // Wrong, continuations not indented far enough
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
for (\=LongTypeName\_t longLoopIndexName = aLongExpression; \\
|
|
\>longLoopIndexName < MAX\_VALUE; \\
|
|
\>longLoopIndexName++) // Right, indented for readability
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item {\bf {\tt IF} Statements}.
|
|
The open curly brace following an {\tt IF} statement must be on the
|
|
following line, indented by one indention level.
|
|
The subsequent lines must be
|
|
indented by an additional one indention level.
|
|
The {\tt ELSE} statement (if present)
|
|
must be on a line by itself.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
if (someCondition) \\
|
|
\>\{ // Describe TRUE condition here\\
|
|
\>\>i = k;\\
|
|
\>\>k = i + 2;\\
|
|
\>\} // Right, curly block indented one indent level, statements one indent more
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
if (someCondition) \\
|
|
\>\{ // Describe TRUE condition here\\
|
|
\>\>i = k;\\
|
|
\>\>k = i + 2;\\
|
|
\>\} \\
|
|
else // Right, ELSE statement on separate line, same indent as IF \\
|
|
\>\{ // Describe FALSE condition here\\
|
|
\>\>i = k * 2; \\
|
|
\>\>k = i + 4; \\
|
|
\>\} // Right, closing curly brace lined up with open brace
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
if (someCondition) // Describe TRUE condition here\\
|
|
\>i = k; // Right, single line block need not have curly braces \\
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
|
|
\item {\bf {\tt FOR} Statements}.
|
|
The open brace following a {\tt for} statement is indented
|
|
one level from the {\tt for} statement itself. Each statement
|
|
in the sub--block is indented one level from the curly brace.
|
|
If the sub--block is a single statement, the curly braces can be
|
|
omitted and the statement indented one level, or optionally appear
|
|
on the same line as the {\tt for} statement.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
for (int i = 0; i < MAX\_COUNT; ++i) \\
|
|
\>\{ // Curly brace indented one level \\
|
|
\>\>sum += i; // Statements indented another one level \\
|
|
\>\>prod *= i; \\
|
|
\>\} // Close brace on same column as open brace \\
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item {\bf {\tt WHILE} Statements}.
|
|
{\tt While} statements are formatted similarly to {\tt IF} statements,
|
|
with curly braces indented one level on separate lines, and the
|
|
inner statements indented another level. If the sub--block has only
|
|
a single line, the curly braces can be omitted, and the statement may
|
|
appear on the same line as the {\tt WHILE} statement.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
while (someCondition) \\
|
|
\>\{ // Right, open brace indented one level \\
|
|
\>\>i = k; // Right, statements indented one level from open brace \\
|
|
\>\>k = i + 2;\\
|
|
\>\} // Right, close brace lines up with open brace
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item {\bf Infinite Loops}.
|
|
Any loop intended to be infinite (of course with a {\tt break} statement
|
|
somewhere) should be of the form:
|
|
|
|
\begin{tt}
|
|
while(true) \\
|
|
{ // Loop until sentinel found\\
|
|
...code here \\
|
|
}
|
|
\end{tt}
|
|
|
|
\item {\bf {\tt SWITCH} Statements}.
|
|
The open curly brace for a {\tt switch} statement will be on the same
|
|
line as the {\tt switch} statement itself. Each {\tt case} statement
|
|
following is indented two columns from the switch statement. Each
|
|
statement in the {\tt case} block is indented two column from the
|
|
{\tt case} statement. The closing curly brace is on a separate line
|
|
by itself, indented two columns from the {\tt switch} statement.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\= \kill
|
|
switch(someCondition) \{ Right, open brace on same line as switch\\
|
|
\>case 0 : // Right, case indented two columns from switch\\
|
|
\>\>i = k; // Right, statements indented two columns from case \\
|
|
\>\>k = i + 2;\\
|
|
\>\>break;\\
|
|
\>case 1 : // Right, case indented two columns from switch\\
|
|
\>\>i = k + 2; // Right, statements indented two columns from case \\
|
|
\>\>k = i + 4;\\
|
|
\>\>break;\\
|
|
\>\} // Right, close brace lines up with case statements
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item {\bf Functions}. Since C and C++ do not allow nested functions,
|
|
all functions start with no indentation at column 0. The open curly
|
|
brace is on a line by itself immediately following the function header
|
|
and formal parameters, also in column 0.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
aa\=aa\=aa\=aa\= \kill
|
|
void Function1(int arg1, double arg2)\\
|
|
\{ // Right, curly brace at column 0\\
|
|
\>int local1 = 0; // Right, local variable at column 2\\
|
|
\>int local2;\\
|
|
\>\\
|
|
\>local2 = local1 + arg1 + arg2; // Right, indented two columns\\
|
|
\>int local3; // Right, variable at same level\\
|
|
\>local3 = Function2(local2);\\
|
|
\>if (someCondition)\\
|
|
\>\>\{\\
|
|
\>\>\>local3 = 0;\\
|
|
\>\>\>local2 = local1;\\
|
|
\>\>\>int local4 = local1 + 1; // Right, variable at same level\\
|
|
\>\>\>Function3(local4);\\
|
|
\>\>\}\\
|
|
\} // Right, close brace at column 0
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\item {\bf Expressions}. Spaces should be used liberally in expressions
|
|
to increase readability. One space before and after each operator,
|
|
excepting the increment and decrement operators, leads to easy--to--read
|
|
expressions. Continued expressions should be indented as far as needed
|
|
for neatness and readability.
|
|
|
|
Examples:
|
|
|
|
\begin{tt}
|
|
i = k * 2 + 3 / var1++; // Right, spacing separating terms \\
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
i = k*2+2/var1++; // Wrong, crowded together and hard to read
|
|
\end{tt}
|
|
|
|
\begin{tt}
|
|
\begin{tabbing}
|
|
someLongVariableName = \=anotherLongVariableName * shorterName + \\
|
|
\>anotherName; // Right, indented to line up
|
|
\end{tabbing}
|
|
\end{tt}
|
|
|
|
\end{enumerate}
|
|
\subsection{Header Files}
|
|
\begin{enumerate}
|
|
\item All header files will have a file name ending with {\tt .h}.
|
|
\item All header files should have a one line comment describing
|
|
the purpose of the header, and comments identifying the
|
|
author and the (approximate) date the file was created.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
// ns3 Network Simulator - TCP Base Class Declaration \\
|
|
// George F. Riley. riley@ece.gatech.edu. \\
|
|
// Georgia Tech, Fall 2006
|
|
\end{tt}
|
|
|
|
\item All header files should have an ``include guard'' to prevent accidental
|
|
inclusion of the file multiple times in a single compilation unit. The include
|
|
guard should be named after the file name. If the file name is \code{foo-bar.h}, then the
|
|
include guard should be named \code{FOO\_BAR\_H}
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\#ifndef FOO\_BAR\_H \\
|
|
\#define FOO\_BAR\_H \\
|
|
|
|
// (Contents of foo-bar.h here
|
|
|
|
\#endif
|
|
\end{tt}
|
|
\item Header files should avoid including other files whenever possible.
|
|
This can often be avoided with judicious use of the
|
|
{\tt class ClassName;} forward declaration.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
// excerpt from application.h \\
|
|
class L4Protocol; \\
|
|
|
|
class Application \{ \\
|
|
.... \\
|
|
AddL4Proto(const L4Protocol\&); \\
|
|
.... \\
|
|
L4Protocol* l4Proto; \\
|
|
\};
|
|
\end{tt}
|
|
|
|
In the above example, the use of the forward declaration for {\tt L4Protocol}
|
|
obviates the need to include {\tt l4proto.h} in the application header
|
|
file.
|
|
|
|
\end{enumerate}
|
|
\subsection{Source Code Files}
|
|
\begin{enumerate}
|
|
\item All souce code files will have a file name ending with {\tt .cc}.
|
|
\item All source code files should have a one line comment describing
|
|
the purpose of the code, and comments identifying the
|
|
author and the (approximate) date the file was created.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
// ns3 Network Simulator - TCP Base Class Implementation \\
|
|
// George F. Riley. riley@ece.gatech.edu. \\
|
|
// Georgia Tech, Fall 2006
|
|
\end{tt}
|
|
|
|
\item All {\tt \#include} directives should be grouped with {\em system}
|
|
files listed first (eg. {\tt \#include <iostream>}), followed by
|
|
\nst\ defined files (eg. {\tt \#include "tcp.h"}). Within a group,
|
|
the includes should be sorted in alphabetical order.
|
|
|
|
Example:
|
|
|
|
\begin{tt}
|
|
\#include <iostream> \\
|
|
\#include <list> \\
|
|
\#include <vector> \\
|
|
|
|
\#include "application.h" \\
|
|
\#include "dumbbell.h" \\
|
|
\#include "simulator.h" \\
|
|
\#include "tcp.h.h"
|
|
|
|
\end{tt}
|
|
\end{enumerate}
|
|
\end{document}
|