ICub Coding Guidelines
- The correct title of this article is iCub Coding Guidelines. The initial letter is shown capitalized due to technical restrictions.
Programming Style
Declarations
Number Per Line
One declaration per line is recommended since it encourages commenting:
int level; // indentation level
int size; // size of table
is preferable to:
int level, size;
Do not put different types on the same line:
int foo, fooarray[]; //WRONG!
Initialization
Initialize local variables where they are declared. The only reason not to initialize a variable where it's declared is if the initial value depends on some computation occurring first.
Placement
Put declarations only at the beginning of blocks. A block is any code surrounded by curly
braces {
and }
.
Don't wait to declare variables until their first use.
Ideally, declare all variables at the beginning of the method or function block.
void myMethod() {
int int1 = 0; // beginning of method block
if (condition) {
int int2 = 0; // beginning of "if" block
...
}
}
Class Declarations
The following formatting rules should be followed:
- No space between a method name and the parenthesis
(
starting its parameter list. - The open brace
{
appears at the end of the same line as the declaration statement. - The closing brace
}
starts a line by itself indented to match its corresponding opening statement.
class Sample {
...
}
- Methods are separated by a blank line.
Statements
Simple Statements
Each line should contain at most one statement. For example:
argv++; // Correct
argc++; // Correct
argv++; argc--; // AVOID!
Compound Statements
Compound statements are statements that contain lists of statements enclosed in braces
{ statements }
. See the following sections for examples.
- The enclosed statements should be indented one more level than the compound statement.
- The opening brace should be at the end of the line that begins the compound statement; the closing brace should begin a line and be indented to the beginning of the compound statement.
- Braces are used around all statements, even single statements, when they are part of a control structure, such as a if-else or for statement. This makes it easier to add statements without accidentally introducing bugs due to forgetting to add braces.
if (condition) {
a = b;
}
else {
a = c;
}
return
Statements
A return statement with a value should not use parentheses unless they make the return value more obvious in some way. For example:
return;
return myDisk.size();
return TRUE;
if
, if-else
, if else-if else
Statements
The if-else
class of statements should have the following form:
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
}
Always use braces { }
, with if
statements.
Don't use
if (condition) //AVOID!
statement;
for
Statements
A for
statement should have the following form:
for (initialization; condition; update) {
statements;
}
while
Statements
A while
statement should have the following form:
while (condition) {
statements;
}
do-while
Statements
A do-while
statement should have the following form:
do {
statements;
} while (condition);
switch
Statements
A switch
statement should have the following form:
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
Every time a case falls through (i.e. when it doesn't include a break
statement),
add a comment where the break statement would normally be.
This is shown in the preceding code example with the
/* falls through */
comment.
Every switch statement should include a default case. The break
in the default case is
redundant, but it prevents a fall-through error if later another case
is added.
Naming Conventions
C vs. C++
Naming conventions make programs more understandable by making them easier to read. Since iCub software uses both the C language and the C++ language, sometimes using the imperative programming and object-oriented programming paradigms separately, sometimes using them together, we will adopt two different naming conventions, one for C and the other for C++. The naming conventions for C++ are derived from the JavaDoc standards.
C++ Language Conventions
The following are the naming conventions for identifiers when using C++ and the object-oriented paradigm.
Identifier Type Rules for Naming Examples Classes Class names should be nouns, in mixed case with class ImageDisplay the first letter of each internal word capitalized class MotorController Methods Method names should be verbs, in mixed case with int grabImage() the first letter in lowercase, with the first int setVelocity() letter of each internal word capitalized Variables variable names should be in mixed case with the int i; first letter in lowercase, with the first letter float f; of each internal word capitalized double pixelValue; Constants The names of variables declared as constants const int WIDTH = 4; should be all uppercase with words separated by underscores _ Type Names Typedef names should use the same naming policy as typedef uint16 ModuleType that used for class names Enum Names Enum names should use the same naming policy as enum PinState { that used for class names. PIN_OFF, Enum labels should should be all uppercase with PIN_ON words separated by underscores _ };
C Language Conventions
The following are the naming conventions for identifiers when using C.
Identifier Type Rules for Naming Examples Functions Function names should be all lowercase with words int display_image() separated by underscores _ void set_motor_control() Variables variable names should be all lowercase with words int i; separated by underscores _ float f; of each internal word capitalized double pixel_value; Constants Constants should be all uppercase with words #define WIDTH 4 separated by underscores _ #define #define and macro names should all uppercase #define SUB(a,b) ( (a) - (b) ) and Macros with words separated by underscores _
And Finally: Where To Put The Opening Brace {
There are two main conventions on where to put the opening brace of a block. In this document, we have adopted the JavaDoc convention and put the brace on the same line as the statement preceding the block. For example:
class Sample {
...
}
while (condition) {
statements;
}
The second convention is to place the brace on the line below the statement preceding the block and it indent it to the same level. For example:
class Sample
{
...
}
while (condition)
{
statements;
}
If you really hate the JavaDoc format, use the second format, but be consistent and stick to it throughout your code.
Programming Practice
C++ Language Conventions
Access to Data Members
Don't make any class data member public without good reason.
One example of appropriate public data member is the case where the class is essentially a
data structure, with no behaviour. In other words, if you would have used a struct instead of a
class, then it's appropriate to make the class's data members public.
C Language Conventions
Use the Standard C syntax for function definitions:
void example_function (int an_integer, long a_long, short a_short)
...
If the arguments don't fit on one line, split the line according to the rules in above.
void example_function (int an_integer, long a_long, short a_short,
float a_float, double a_double)
...
General Issues
Conditional Compilation
Avoid the use of conditional compilation. If your code deals with different configuration
options, use a conventional if-else
construct. If the code associated
with either clause is long, put it in a separate function. For example, please write:
if (HAS_FOO) {
...
}
else {
...
}
instead of:
#ifdef HAS_FOO
...
#else
...
#endif
Writing Robust Programs
Avoid arbitrary limits on the size or length of any data structure,
including arrays, by allocating all data structures dynamically.
Use malloc
or new
to create data-structures of the
appropriate size. Remember to avoid memory leakage by always using free
and delete
to deallocate dynamically-created data-structures.
Check every call to malloc
or new
to see if it returned
NULL
.
You must expect free
to alter the contents of the block that was freed.
Never access a data structure after it has been freed.
If malloc
fails in a non-interactive program, make that a fatal error.
In an interactive program, it is better to abort the current command and
return to the command reader loop.
When static storage is to be written during program execution, use explicit C or C++
code to initialize it. Reserve C initialize declarations for data that will not be
changed. Consider the following two examples.
static int two = 2; // two will never alter its value
...
static int flag;
flag = TRUE; // might also be FALSE
Constants
Numerical constants (literals) should not be coded directly, except for -1, 0, and 1, which can
appear in a for
loop as counter values.
Variable Assignments
Avoid assigning several variables to the same value in a single statement. It is hard to read.
Do not use the assignment operator in a place where it can be easily confused with the equality
operator.
if (c++ = d++) { // AVOID!
...
}
should be written as
if ((c++ = d++) != 0) {
...
}
Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler.
d = (a = b + c) + r; // AVOID!
should be written as
a = b + c;
d = a + r;
Parentheses
Use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems. Even if the operator precedence seems clear to you, it might not be to others --- you shouldn't assume that other programmers know precedence as well as you do.
if (a == b && c == d) // AVOID!
if ((a == b) && (c == d)) // USE
Standards for Graphical Interfaces
When you write a program that provides a graphical user interface (GUI), you should use a cross-platform library. At the very least, it must possible to compile your GUI code for both a Window environment and a Linux environment.
Error Messages
Error messages should look like this:
function_name: error message
License Messages
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
<Program name and version>
Copyright (C) <year> <name of author>, <author institute>
RobotCub Consortium, European Commission FP6 Project IST-004370
email: <firstname.secondname>@robotcub.org
website: www.robotcub.org
This program comes with ABSOLUTELY NO WARRANTY.
Permission is granted to copy, distribute, and/or modify this program
under the terms of the GNU General Public License, version 2
or any later version published by the Free Software Foundation;
see http://www.robotcub.org/icub/license/gpl.txt