Difference between revisions of "Standards for Programming Practice"

From David Vernon's Wiki
Jump to: navigation, search
Line 13: Line 13:
  
 
  void example_function (int an_integer, long a_long, short a_short,
 
  void example_function (int an_integer, long a_long, short a_short,
                          float a_float, double a_double)
+
                      float a_float, double a_double)
 
  ...
 
  ...
  
Line 25: Line 25:
  
 
Include files should protect against multiple inclusion through the use of macros that guard the file. Specifically, every include file should begin with the following:
 
Include files should protect against multiple inclusion through the use of macros that guard the file. Specifically, every include file should begin with the following:
  #ifndef FILENAME_H
 
  #define FILENAME_H
 
  ...  header file contents go here
 
  #endif /* FILENAME_H */
 
In the above, you should replace FILENAME with the root of the name of the include file being guarded e.g. if the include file is cognition.h you would write the following:
 
  #ifndef COGNITION_H
 
  #define COGNITION_H
 
  ...  header file contents go here
 
  #endif /* COGNITION_H */
 
  
Conditional Compilation
+
#ifndef FILENAME_H
 +
#define FILENAME_H
 +
...  header file contents go here
 +
#endif /* FILENAME_H */
 +
 
 +
In the above, you should replace <code>FILENAME</code> with the root of the name of the include file being guarded e.g. if the include file is cognition.h you would write the following:
 +
 
 +
 #ifndef COGNITION_H
 +
#define COGNITION_H
 +
  ...  header file contents go here
 +
#endif /* COGNITION_H */
 +
 
 +
===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:
 
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) {
+
 
      ...
+
if (HAS_FOO) {
}
+
    ...
else {
+
}
... }
+
else {
 +
    ...  
 +
}
 +
 
 
instead of:
 
instead of:
  #ifdef HAS_FOO
+
 
      ...
+
#ifdef HAS_FOO
#else ...
+
    ...
#endif
+
#else
Writing Robust Programs
+
    ...
 +
#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.
 
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.
+
Check every call to malloc or new to see if it returned <code>NULL</code>.
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 ini- tialize 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
+
You must expect <code>free</code> to alter the contents of the block that was freed. Never access a data structure after it has been freed.
  ...
+
 
  static int flag;
+
 
  flag = TRUE;        // might also be FALSE
+
If <code>malloc</code> 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.
Constants
+
 
 +
 
 +
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.
 
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
+
 
 +
===Variable Assignments===
 +
 
 
Avoid assigning several variables to the same value in a single statement. It is hard to read.
 
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.
 
Do not use the assignment operator in a place where it can be easily confused with the equality operator.
  
if (c++ = d++) { // AVOID!
+
if (c++ = d++) { // AVOID!
      ...
+
    ...
}
+
}
 +
 
 
should be written as
 
should be written as
  if ((c++ = d++) != 0) {
 
      ...
 
}
 
  
 +
if ((c++ = d++) != 0) {
 +
    ...
 +
}
  
 
Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler.
 
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!
+
 
 +
d = (a = b + c) + r; // AVOID!
 +
 
 
should be written as
 
should be written as
  a = b + c;
+
 
  d = a + r;
+
a = b + c;
Parentheses
+
d = a + r;
Use parentheses liberally in expressions involving mixed operators to avoid operator precedence prob- lems. 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!
+
===Parentheses===
if ((a == b) && (c == d)) // USE
+
 
Standards for Graphical Interfaces
+
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.
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. The FLTK GUI library [23] satisfies this requirement.
+
 
Error Messages
+
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. The FLTK GUI library satisfies this requirement.
 +
 
 +
===Error Messages===
 
Error messages should look like this:
 
Error messages should look like this:
  function_name: error message
 
  
Copyright Messages
+
function_name: error message
 +
 
 +
===Copyright Messages===
  
 
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
 
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) 2014 DREAM Consortium
+
<Program name and version>
FP7 Project 611391 co-funded by the European Commission
+
Copyright (C) 2014 DREAM Consortium
Author:  <name of author>, <author institute>
+
FP7 Project 611391 co-funded by the European Commission
Email:  <preferred email address>
+
Author:  <name of author>, <author institute>
Website: www.dream20202.eu
+
Email:  <preferred email address>
This program comes with ABSOLUTELY NO WARRANTY.
+
Website: www.dream20202.eu
 +
This program comes with ABSOLUTELY NO WARRANTY.

Revision as of 00:50, 30 August 2014

WORK IN PROGRESS ... DON'T READ

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 like this,

void example_function (int an_integer, long a_long, short a_short,
                      float a_float, double a_double)
...

Declarations of external functions and functions to appear later in the source file should all go in one place near the beginning of the file (somewhere before the first function definition in the file), or else it should go in a header file.

Do not put extern declarations inside functions.

General Issues

Use of Guards for Header Files

Include files should protect against multiple inclusion through the use of macros that guard the file. Specifically, every include file should begin with the following:

#ifndef FILENAME_H
#define FILENAME_H
...  header file contents go here
#endif /* FILENAME_H */

In the above, you should replace FILENAME with the root of the name of the include file being guarded e.g. if the include file is cognition.h you would write the following:

 #ifndef COGNITION_H

#define COGNITION_H
 ...  header file contents go here
#endif /* COGNITION_H */

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. The FLTK GUI library satisfies this requirement.

Error Messages

Error messages should look like this:

function_name: error message

Copyright 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) 2014 DREAM Consortium
FP7 Project 611391 co-funded by the European Commission
Author:  <name of author>, <author institute>
Email:   <preferred email address>
Website: www.dream20202.eu
This program comes with ABSOLUTELY NO WARRANTY.