Skip to content

Coding style

David Anderson edited this page Feb 2, 2026 · 6 revisions

Some rules for writing code in BOINC. In general:

  • Make the code short and simple.
  • Split up long functions.
  • Imitate the style and structure of code that's already there, even if you don't like it.
  • If you're writing a function that might be of general utility, make it general, and put it in lib/ or html/inc. Check first - it might already be there.
  • Don't copy and paste code. Use functions.

Error codes

Most functions should return an integer error code. Nonzero means error. See lib/error_numbers.h for a list of error codes. Exceptions:

  • PHP database access functions, which use the mysql_* convention that zero means error, and you call mysql_error() or mysql_error_string() to find details.
  • Functions that return whether a condition holds; such functions return bool and should have descriptive names like is_job_finished().
  • Functions that return a number or other type, and for which no errors are possible.

Calls to functions that return an error code should check the code. Generally they should return non-zero on error, e.g.:

retval = blah();
if (retval) return retval;

Don't use exceptions.

Code documentation

  • All files have a comment at the top saying what's in the file (and perhaps what isn't).
  • Functions are preceded by a comment saying what they do.
  • structs and classes are preceded by a comment saying what they represent.

Naming

  • Names are descriptive without being verbose (local variables names may be short).
  • Class and type names, and #defined symbols, are all upper case, with underscores to separate words.
  • Variable and function names are all lower case, with underscores to separate words.
  • No mixed case names.

Indentation

  • Each level of indentation is 4 spaces (not a tab).
  • Multi-line function call:
func(
    blah, blah, blah, blah, blah,
    blah, blah, blah, blah, blah
);
  • switch statements: case labels are at same indent level as switch
switch (foo) {
case 1:
    ...
    break;
case 2:
    ...
    break;
}

Braces

  • Opening curly brace goes at end of line (not next line):
if (foobar) {
    ...
} else if (blah) {
    ...
} else {
    ...
}
  • Always use curly braces on multi-line if statements.
if (foo)
    return blah;     // WRONG
  • 1-line if() statements are OK:
if (foo) return blah;

Constants

  • There should be few numeric constants in code. Use defined symbols instead. Put the defines at the top of the file or in the appropriate include file.

Comments and #ifdefs

  • For C++ and PHP, use // for all comments.
  • End multi-line comments with an empty comment line, e.g.
// This function does blah blah
// Call it when blah blah
//
function foo() {
}

Range-based for

The range-based for statement, introduced in C++ 11, replaces

for (unsigned int i=0; i<results.size(); i++) {
    RESULT& r = results[i];
    ...
}

with

for (RESULT& r: results) {
    ...
}

PHP has an analogous foreach statement. Use range-based for where possible, because

  • it's shorter and easier to read.
  • it eliminates bugs where i is inadvertently modified in the loop

Another readability issue:

bool SOME_CLASS::check(char *x) {
    for (unsigned int i=0; i<items.size(); i++) {
        if (!strcmp(items[i].name, x)) {
        ...

where the vector 'items' is a member of SOME_CLASS. The problem: this code doesn't show the type of the list items; you have to look at the .h file. A range-based for shows you the type (ITEM in this case):

bool SOME_CLASS::check(char *x) {
    for (ITEM& item: items) {
        if (!strcmp(item.name, x)) {
        ...

Notes:

  • Sometimes you need a loop counter. In that case you can either use the original for syntax, or use a range-based for and add your own counter.

  • If you're going to delete items in the list, don't use a range-based for; use your own vector iterator.

  • C++ lets you use 'auto':

for (auto& r: results) {
    ...
}

but avoid this because it hides the type of r, making the code harder to understand; avoid 'auto' in general for this reason.

C++ specific

  • C++ .h files often contain both interface and implementation. Clearly divide these.

Includes

  • A .cpp file should have the minimum set of #includes to build that particular file (in particular, the includes needed by foo.cpp should be in foo.cpp, not foo.h).
  • foo.cpp should include foo.h
  • For readability, includes should be ordered from general (<stdio.h>) to specific (foo.h). However, this order shouldn't matter.

Extern declarations

  • foo.h should have extern declarations for all public functions and variables in foo.cpp. There should be no extern statements in .cpp files.

Use of static

  • If a function or variable is used in only its same file, declare it static.

Unless there's a compelling reason:

  • Avoid operator and function overloading.
  • Avoid templates.
  • Avoid stream I/O; use printf() and scanf().
  • Use typedef (not #define) to define types.
  • Don't use memset() or memcpy() to initialize or copy classes that are non-C compatible. Write a default constructor and a copy constructor instead.
  • Avoid dynamic memory allocation. Functions shouldn't return pointers to malloc'd items.

Structure definitions

struct FOO {
    ...
};

You can then declare variables as:

FOO x;

Comments

Comment out blocks of code as follows:

#if 0
    ...
#endif

PHP specific

HTML

PHP scripts should output "HTML 4.01 Transitional". The HTML should pass the W3C validator. This means, e.g., you must have quotes around attributes that have non-alpha characters in them. However, all-alpha attributes need not have quotes, and tags like <br> and <p> need not be closed.

The HTML need not be XHTML.

This means no self-closing tags like <br />.

Getting POST and GET data

Do not access $_POST or $_GET directly. Use get_int(), get_str(), post_int() and post_str() (from util.inc) to get POST and GET data.

Database access

  • Use the database abstraction layer.
  • If a POST or GET string value will be used in a database query, use BoincDb::escape_string to escape it.

Clone this wiki locally