From BlenderWiki

Jump to: navigation, search

Coding Style

There are only two important rules:

  • When making changes, conform to the style and conventions of the surrounding code.
  • Strive for clarity, even if that means occasionally breaking the guidelines. Use your head and ask for advice if your common sense seems to disagree with the conventions.

Naming

  • Use descriptive names for global variables and functions.
  • Public function names should include module identifier, object and property they're operating and operation itself. Very familiar with RNA callbacks names: BLI_object_foo_get(...) / BLI_object_foo_set(...):
/* Don't: */
ListBase *curve_editnurbs(Curve *cu);
/* Do: */
ListBase *BLI_curve_editnurbs_get(Curve *cu);
  • Local variables should be short and to the point.

Macros, Enums, Inline functions

  • Names of macros defining constants and labels in enums should be capitalized.
  • Macro names should be capitalised.
  • Enums used in DNA files should have explict values assigned.

Operators and statements

  • Spaces should be used around assign operators (=, +=, /= and so), one space on each side of it:
/* Don't: */
foo= bar;
/* Do: */
foo = bar;
  • Space should be used between statement and brace:
/* Don't: */
for(ob = bmain->object.first; ob; ob = ob->id.next) {}
for( ob = bmain->object.first; ob; ob = ob->id.next ) {}
/* Do: */
for (ob = bmain->object.first; ob; ob = ob->id.next) {}
  • Body of switch statement should be indented, so case keyword has next indentation level relative to switch, body of case statement has got next indentation level relative to case:
/* Don't: */
switch(wmn->category) {
case NC_SPACE:
		ED_region_tag_redraw(ar);
		break;
default:
		break;
}
/* Do: */
switch (wmn->category) {
	case NC_SPACE:
			ED_region_tag_redraw(ar);
			break;
	default:
			break;
}


Braces

This section covers placement of braces.

Functions should always have braces on new lines.

/* Don't: */
void func(void) {
    return 1;
}
/* Do: */
void func(void)
{
    return 1;
}

For everything else, braces should be placed on the same line.

/* Don't: */
    if (a == b)
    {
        d = 1;
    }
/* Do: */
    if (a == b) {
        d = 1;
    }
/* Don't: */
    for (i = 0; i < 10; i++)
        {
        func();
        }
/* Do: */
    for (i = 0; i < 10; i++) {
        func();
    }

Exceptions to Braces on Same Line

When flow control (if, for, while) is broken up into multiple lines, it reads better to have the brace on its own lines.

/* Don't: */
    if ((very_long_function_check(that, has, many, arguments)) &&
        (another_very_long_function(some, more, arguments)) &&
        some_more_checks_this_gets_tedious(but, its, readable)) {
        some_other_check_this_could_be_confusing ? func_a() : func_b();
    }
 
/* Do: */
    if ((very_long_function_check(that, has, many, arguments)) &&
        (another_very_long_function(some, more, arguments)) &&
        some_more_checks_this_gets_tedious(but, its, readable))
    {
        (some_other_check_this_could_be_confusing && n) ? func_a() : func_b();
    }

Notice how the lines run together when the brace doesn't get its own line.

/* Don't: */
	for (a = long_function_name();
	     a < some_long_check;
	     a = some_long_iterator()) {
	    a_other = a;
	}
 
/* Do: */
	for (a = long_function_name();
	     a < some_long_check;
	     a = some_long_iterator())
	{
	    a_other = a;
	}

Braces with Macros

When a macro simply replaces a for loop, brace is on same line, eg...

#define BM_ITER_MESH(ele, iter, bm, itype) \
       for (ele = BM_iter_new(iter, bm, itype, NULL); ele; ele = BM_iter_step(iter))
	BM_ITER_MESH (h, &iter, bm, t) {
		/* body */
	}

But for macros that have a begin/end, do this...

	RNA_PROP_BEGIN (ptr, itemptr, prop)
	{
		/* body */
	}
	RNA_PROP_END;

Indentation

  • In C/C++ sources use TABs for indenation. Spaces are only allowed to keep wrapped part of line aligned with first part of line.
  • The whole idea behind indentation is to clearly define where a block of control starts and ends. Always indent when needed - that is, after if, do, while statements, function declarations, and so on.
  • When defining an argument list over multiple lines, the lines preferrable be indented with spaces such that the argument lines up under the opening brace of the argument list. For example:
/* Don't: */
void function_foo(arg1, arg2, ..., argN,
    argN + 1, ..., argM,
    argM + 1, argM + 2);
void function_foo(arg1,
                  arg2,
                  arg3);
/* Do: */
void function_foo(arg1, arg2, ..., argN,
                  argN + 1, ..., argM,
                  argM + 1, argM + 2);
/* --- snip --- *//* --- 120 chars long --- */
  • It is also OK to use two tabs as indentation for wrapped lines in cases if editor doesn't support alignment automatically or in cases when function name and data types used in arguments are long:
/* Don't: */
/*   --- Line is longer than 120 characters  ---*/
static struct ReallyLongStructName *very_long_function_name_we_infact_have_a_handful_of_these(const struct ReallyLongStructName *some_arg,
                                                                                              void (*some_callback_with_many_args)(bContext *C, wmWindowManager *, int *arg1, int *arg2));
/* Do: */
static struct ReallyLongStructName *very_long_function_name_we_infact_have_a_handful_of_these(
        const struct ReallyLongStructName *some_arg,
        void (*some_callback_with_many_args)(bContext *C, wmWindowManager *, int *arg1, int *arg2));
  • When splitting if statement it's preferrable to split it on disjunction operation and keeping wrapped conditions:
if ((size = VectorObject_Check(value)     ? ((VectorObject *)value)->size : 0) ||
    (size = EulerObject_Check(value)      ? 3 : 0) ||
    (size = QuaternionObject_Check(value) ? 4 : 0) ||
    (size = ColorObject_Check(value)      ? 3 : 0))
{ /* in this case wrapped opening brace is reading easier */
	/* code - snip */
}

Macro Indentation

for trivial cases this is not needed, however when blocks of definitions become confusing, 2 space indent should be used after the hash. eg.

#ifdef __BLI_MATH_INLINE_H__
#  ifdef _MSC_VER
#    define MINLINE static __forceinline
#    define MALWAYS_INLINE MINLINE
#  else
#    define MINLINE static inline
#    define MALWAYS_INLINE static inline __attribute__((always_inline))
#  endif
#else
#  define MINLINE
#  define MALWAYS_INLINE
#endif

NOT

#ifdef __BLI_MATH_INLINE_H__
#ifdef _MSC_VER
#define MINLINE static __forceinline
#define MALWAYS_INLINE MINLINE
#else
#define MINLINE static inline
#define MALWAYS_INLINE static inline __attribute__((always_inline))
#endif
#else
#define MINLINE
#define MALWAYS_INLINE
#endif

Breaking long lines

  • Lines should not be longer than 120 characters (columns) long.
  • Statements longer than 120 columns will be broken into sensible chunks. Descendants are always substantially shorter than the parent and are placed substantially to the right. The same applies to function headers with a long argument list. Long strings are as well broken into shorter strings.

Generally the only exceptions are for comments with example commands or URLs - to make cut and paste easier.

The other exception is for those rare cases where letting a line be longer (and wrapping on an 120-character window) is actually a better and clearer alternative than trying to split it into two lines. Sometimes this happens, but it's extremely rare.

DO NOT alter somebody else's code to re-wrap lines (or change whitespace) just because you found something that violates the rules. Let the group/author/leader know, and resist the temptation to change it yourself.

Commenting and documentation

  • Comments should explain what the code is doing, not how. The how should be more or less obvious from the way the code is written.
  • C code should use C-style comments only:
/* this is a C comment */
// This is a C++ comment, not a C comment
  • When using multiline comments, markers (star character, '*') should be used in the beginning of every line of comment:
/* special case: ima always local immediately. Clone image should only
 * have one user anyway. */

NOT

/* special case: ima always local immediately. Clone image should only
   have one user anyway. */
  • XXX marker should be used only in comments, describing usage of a non-obvious solution caused by some design limitations which better be resolved after rethinking of design.

Related Topics