Estilo de programación

This document is not complete. If a guideline for a particular format is missing, follow the style of existing the code (prefer using Haiku sources as a reference for this). If you have suggestions for things that should be clarified better, etc. please let us know. Please don't send us suggestions of the kind "I like this indenting style better, could we switch?".

Some code doesn't match our guidelines in some places, due mainly to time constraints. Help with cleaning up the code is very welcome.

Rather than advocating a given coding style, the main goal here is code consistency - after a stream of external contributions and patches we would like the Haiku code base to remain clean, uniform, easy to read and maintain.


Make your code not stick out -- make it consistent with the rest of the code you are contributing to. You will see this rule stressed over and over throughout the guidelines and when submitting patches.

Indenting and white space

  • Use tabs to indent blocks. Set your editor to 4 spaces per tab.
  • The Haiku indenting style is close to the K&R style.
  • Functions/classes in namespaces are not indented.
  • In general you use one tab per expression level, see the examples below.

First, let's use some examples to illustrate the main formatting conventions:

class Foo : public Bar {
    virtual                 ~Foo();
    virtual void                SomeFunction(SomeType* argument);
    // indent long argument lists by a tab:
    virtual const char*         FunctionWithLotsOfArguments(const char* name,
                            const char* path, const char* user);
        int32               _PrivateMethod();
    static  int32               _SomeStaticPrivateMethod();
        int32               fMember;
        const char*         fPointerMember;
// The ':' always comes on its own line, initializers following
Foo::Foo(int32 param)
    Bar(int32* param),
/*! Function descriptions are using doxygen style. Please note, this is not
    a place for end-user documentation, but for documentation that helps
    understanding the code, and using the functions correctly.
template<class T>
const T*
Foo<T>::Bar(const char* bar1, T bar2)

static int32
    return 42;

if (someCondition) {
        // comments that only affect a single line are usually
        // written after it, and are indented by a single tab
} else if (someOtherCondition) {
if (someVeryVeryLongConditionThatBarelyFitsOnALine
    && someOtherCondition) {
    // && operator on the beginning of the next line,
    // indented by a tab
if (someVeryVeryLongConditionThatBarelyFitsOnALine
    && (someVeryLongNestedConditionPart1
        || someVeryLongNestedConditionPart2)
    && lastPartOfSomeVeryVeryLongCondition
        != 0) {
    // indent one tab per expression level
if (fMemberPointer->VeryLongFunctionCall(uint32 argument1,
        uint32 argument2, uint32 argument3) != NULL
    && someOtherCondition) {
    // function call parenthesis count as an expression
    // level thus the additional tab on the second line.
    localVariable = AnotherLongFunction(uint32 argument1,
        uint32 argument2, uint32 argument3);
        // For this simple assignment though
        // an additional tab wouldn't help readability
    anotherVariable = fSomeUselessRGBColor.alpha *
        ( +
            + +
        / 3 + fBrightness;
        // This one spans more than two lines, we add
        // a tab to distinguish the expression level
        // in parenthesis
for (int32 index = 0; index < count; index++) {
// omit braces for single line statements, place statement on a new line
// (but always use braces around multi-line statements)
if (condition)
for (int32 index = 0; index < count; index++)
// switch statement formatting
switch (condition) {
    case label1:
    case label2:
        // need extra curly brackets here because of count
        // declaration
        int32 count;
    CallingSomeFunction(firstArgument * 2 + someMoreStuff,
        secondArgument, thirdArgument);
        // indent long argument lists by a tab
    const rgb_color kNeonBlue = {10, 10, 50, 255};

Misc. formatting

  • A line must not have more than 80 columns; when wrapping a line, you usually indent one extra tab, but that can get more depending on the contents.
  • Put exactly two blank lines between functions.
  • Include a newline at every file end.


  • Use self-describing well chosen identifiers whenever possible. Avoid identifiers such as r (hard to search for), aMessage, theView, MyDraw (who's draw?). Avoid identifier pairs such as ProcessMessage and DoProcessMessage, AddTasks and AddTasks1. Use names such as rect, message, invokeMessage, view, targetView, DrawBorder, ProcessMessage and ProcessMessageInternals or ProcessMessageDetails, etc.
  • Classes, structs, type names, namespaces and function names start with uppercase letters and use InterCapsFormatting (no underlines).
  • variables start with lowercase letters and use interCapsFormatting.
  • member variables start with f like so:

        int32 fMemberVariable;

  • constants start with a k like so:

        const uint32 kOpenFile = 'open';

    (note that this is different from the standard Be API constant names)

  • global variables are prefixed with a 'g', static variables with an 's' using the same scheme as above.
  • private methods are prefixed with an underscore.

Variable declarations

  • declare variables as local in scope where possible, avoid declaring all variables at the top of a function like you have to do in C. The advantages here are it is easier to make sure variables are properly initialized and small code snippets are easier to copy-paste around.
  • Use descriptive names, avoid reusing a single temporary variable for different purposes.
  • Use full names such as message over abbreviations such as msg. Use rect, frame, bounds over r, menuItem over mi.

Use Haiku-defined APIs, types, etc.

  • Prefer using a Haiku API utility call over "rolling your own".
  • Prefer using BObjectList over BList. BObjectList provides type-safety, optional item ownership and is designed such that additional template instantiations will not grow the code considerably.
  • Prefer BString over malloc, strdup, free, etc. for string operations.
  • Prefer BString << operators over fixed size buffers and sprintf.
  • Prefer using types defined in SupportDefs.h such as int32, uint32, over int, long, etc. Use status_t over int, int32 where errors are returned. Use off_t over int64 where appropriate.


  • Comment your code properly.
  • Prefer C++ style comments.
  • Comment properly but not excessively. Here are some examples of excessive commenting:

        index++; // increment the index
        /* InitProgress
        InitProgress(int param1)
  • Prefer commenting over and under the commented line (over when a comment relates to a chunk of code, under and indented by a tab when it relates to one specific line.

        // the trash window needs to display a union of all the
        // trash folders from all the mounted volumes
        // (comment about a block of code)
        BVolumeRoster volRoster;
        BVolume volume;
        while (volRoster.GetNextVolume(&volume) == B_OK) {
            if (!volume.IsPersistent())

            // have to node monitor ahead of time because
            // Model will cache up the file type and preferred
            // app (comment about the above line)
  • Avoid comments on the same line that create long lines (prefer comments on a separate line in general

        if (this < is && a < very && long != condition) { // ...

        if (this < is && a < very && long != condition) {
            // this comment is about the long condition
            // above and is much easier to read!
  • >Do not annotate your comments with your name or initials -- when your patch gets submitted, SVN will have your name in the checkin log. Anyone can identify your code that way.
  • Avoid expressing your sentiments in comments, do not include comments like this:
  •     // this is a hack!

    Instead explain why you consider the respective code a hack:

        // the following code is fragile because it doesn't
        // handle overflows properly
  • The preferred format for source file copyright and license notices is:

     * Copyright 2004-2007 Haiku Inc. All rights reserved.
     * Distributed under the terms of the MIT License.
     * Authors:
     *      Jonathan Smith, optional@email
     *      Developer Name, optional@email

    In case everything is copyrighted to "Haiku Inc." and authors are listed in lexicographic order by last name.

  • Public headers should always be copyrighted to "Haiku Inc." and don't list any authors.
  • In case you prefer to keep the copyright to yourself, the license header should look like the following; multiple authors can be listed like in this example:

     * Copyright 2007 Jane Doe, optional@email
     * Copyright 2003-2005 Some Developer, optional@email
     * All rights reserved. Distributed under the terms of the MIT License.
  • In some cases you might have to extend the copyright list of an existing file. Instead of using the alternative scheme like in the latter example the preferred method is to add a copyright line for "Haiku Inc." and then list authors like in the first example.
  • In header files, there is no blank line between license text and header guard.
  • After the copyright header (including the header guard in header files), there are exactly two blank lines before the rest contents.

Dead code and Debugging code

  • Do not leave dead, commented or printfs behind. These days bdb does a great job eliminating the need for most debugging printfs. Use ASSERTs for debugging purposes. Include debugging code in DEBUG blocks. Make sure debugging code compiles (make sure your change doesn't break existing debugging code; if it does, fix the debugging code as a part of the change) without warnings and stays correct. Use all the other tools from Debug.h to your advantage.


  • Use new-style casts (dynamic_cast, static_cast, const_cast, reinterpret_cast) over old-style.
  • Use const properly.
  • Prefer stack-allocated objects over heap-allocated ones whenever possible.
  • Use AutoLock, etc. for all locking and other resource acquisition; don't use Lock() and Unlock() on a BLocker directly. Don't use BAutolock, use the AutoLock template instead.
  • Don't assign in if, while statements:

        if ((err = entry.GetRef(&ref)) == B_OK)

  • Avoid using assignments in while loops, don't use:

        BMenuItem* item;
        int32 index = 0;
        while ((item = ItemAt(index++)) != NULL) {

    Instead use wordier but as efficient for:

        for (int32 index = 0; ; index++) {
            BMenuItem* item = ItemAt(index);
            if (item == NULL)
  • Don't check for NULL before delete and free:

        // wrong
        if (fIcon)
            delete fIcon;
        // wrong
        if (fIconBuffer)
  • Don't put parentheses around return values:

        // wrong
        return (fList.ItemAt(index));
  • Don't put redundant parentheses in if statements:

        // wrong
        if ((a == 3) && (b != 4))
  • However, use parenthesis when checking bitmasks, and always use this form:

        if ((a & 3) != 0 && (b & 4) == 0)
        // wrong - C/C++ operator precedence works differently
        if (a & 3 && xyz)
  • Use inlines sparingly.
  • Use constructor initializer lists over initializing members inside the constructor body
  • Use built-in false/true instead of FALSE/TRUE #defines.
  • Alphabetize #include statements, group "includes" and  separately.
  • While the header that belongs to a source file should be included first to ensure self-containment, all other headers are specified from most general (POSIX) to most specific (local directory). In order to alphabetize them, please group them by API origin, like (but without the comments, of course):

    #include "ThisClass.h"
    // POSIX API headers
    #include <stdio.h>
    #include <string.h>
    // Haiku API headers
    #include <File.h>
    #include <OS.h>
    #include <PrivateHeader.h>
    #include "OtherLocalHeaders.h"
  • Don't use pathname/include.h if they aren't necessary; (like for sys/stat.h).
  • Use NULL instead of 0 for pointers.
  • Avoid gotos.
  • Don't use constructor call syntax for initializing pointers, etc. to NULL like this:

        // wrong
        BView* view(NULL);

    Use the more traditional assignment:

        BView* view = NULL;

    (Don't confuse this with the appropriate use of constructor calls for stack based objects and objects allocated with new).

  • When comparing a function call result/variable with a constant, don't place the constant on the left side of the comparison like this:

        if (B_OK == file.InitCheck()) // don't use this style

    Programmers use this to make sure they do not end up assigning instead of comparing. The notation is a bit unusual though, placing the more important function call/variable to the less prominent position on the right. Haiku does not use this notation, a mistaken assignment will get caught by a warning.

  • Prefer C-style headers (string.h, stdlib.h) over their C++ equivalents (cstring, cstdlib): Haiku's headers are generally C++ safe, and don't need this workaround.

Style Checker Tools

While the following tools still miss some issues and sometimes report false positives, they are most of the time correct and help to spot the most common issues. Those are still in development and improvements are of course welcomed.

  • is a stand-alone python program (found in the Haiku source tree in src/tools/checkstyle/). It reports style problems on the standard output and also generates an easy to read highlighted HTML report. Example:
    python src/tools/checkstyle/ src/apps/deskcalc

    Assuming you are at the root of the Haiku tree, this will check the src/apps/deskcalc directory recursively. Try the --help option to see the usage.

  • The Style Check Script for Vim (original here) is a script that integrates with the Vim text editor.