[[PageOutline]] = BOINC coding style = == All languages == #all-lang === Code factoring === #factoring * If code is repeated, factor it out and make it into a function. * If a function becomes longer than 100 lines or so, split it up. * If a file is becoming 'landfill', split it up. * C++ `.h` files often contain both interface and implementation. Clearly divide these. === Code documentation === #docs * `.cpp` 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 are. === Naming === #naming * Names should be 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 === #indent * 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; } }}} === Constants === #constants * There should be few numeric constants in code. Generally they should be `#define`s. === Braces === #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; }}} === Comments and #ifdefs === #comments * Use `///` for all comments. The documentation is generated using Doxygen, so you should have a look at this example: {{{ /// Brief description for class test. /// A more elaborate description for class test, /// could be more than one line. class Test { public: /// A constructor. /// A more elaborate description of the constructor. Test(); /// A destructor. /// A more elaborate description of the destructor. ~Test(); /// a normal member taking two arguments and returning an integer value. /// @param a an integer argument. /// @param s a constant character pointer. /// @see Test() /// @see ~Test() /// @see testMeToo() /// @see publicVar() /// @return The test results int testMe(int a,const char *s); /// A pure virtual member. /// @see testMe() /// @param c1 the first argument. /// @param c2 the second argument. virtual void testMeToo(char c1,char c2) = 0; /// a public variable. /// Details. int publicVar; /// a function variable. /// Details. int (*handler)(int a,int b); }; }}} * Comment out blocks of code as follows: {{{ #if 0 ... #endif }}} == C++ specific == #cpp === Includes === #includes * A `.cpp` file should have the minimum set of #includes to get that particular file to compile (e.g. the includes needed by {{{foo.cpp}}} should be in {{{foo.cpp}}}, not {{{foo.h}}}). * foo.cpp should include foo.h first; after that, includes should be ordered from general (``) to specific (`shmem.h`). === Extern declarations === #extern * {{{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 === #static * If a function or variable is used in only one file, declare it {{{static}}}. === Things to avoid unless there's a truly compelling reason: === #try-avoid * Operator or function overloading. * Templates. === Things to avoid === #avoid * 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. === Error codes === #error-codes * (Almost) all functions should return an integer error code. Nonzero means error. See [source:trunk/boinc/lib/error_numbers.h lib/error_numbers.h] for a list of error codes. * 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; }}} === Structure definitions === #structs {{{ struct FOO { ... }; }}} You can then declare variables as: {{{ FOO x; }}} == PHP specific == #php === HTML === #html PHP scripts should output "HTML 4.01 Transitional". The HTML should pass the [http://validator.w3.org/ 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
and

need not be closed. The HTML need not be XHTML. This means no self-closing tags like `
`. === Getting POST and GET data === #post-and-get 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. These undo the effects of PHP magic quotes. === Database access === #database-access * Use the [PhpDb database abstraction layer]. * If a POST or GET value will be used in a database query, use `BoincDb::escape_string` to escape it.