Hacking:Code style conventions

From Seamly
Revision as of 11:49, 9 June 2016 by Dismine (talk | contribs) (→‎Names)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

General[edit | edit source]

Max length of source code line equal 120 characters. Put "//---" cars in front of function definitions with maximum length (120) :

//---------------------------------------------------------------------------------------------------------------------

Don't use

using namespace MyNamespace

C++ namespaces and the using namespace MyNamespace statement can confuse lupdate. It will interpret VClass::tr like MyNamespace::VClass::tr. Runtime translation of these strings will fail because of that.

Indentation[edit | edit source]

Use spaces, not tabs. 4 spaces instead one real tab. Tabs should only appear in files that require them for semantic meaning, like Makefiles.

A case label should be indented with its switch statement. The case statement is indented too.

switch (condition) 
{
    case fooCondition:
    case barCondition:
        i++;
        break;
    default:
        i--;
}

Spacing[edit | edit source]

Do not place spaces around unary operators.

i++;

Do place spaces around binary and ternary operators.

y = m * x + b;
f(a, b);
c = a | b;
return condition ? 1 : 0;

Do not place spaces before comma and semicolon.

for (int i = 0; i < 10; ++i)
{
    doSomething();
}

f(a, b);

Place spaces between control statements and their parentheses.

if (condition)
{
    doIt();
}

Do not place spaces between a function and its parentheses, or between a parenthesis and its content.

f(a, b);

Line breaking[edit | edit source]

Each statement should get its own line.

x++;
y++;
if (condition)
{
    doIt();
}

Braces[edit | edit source]

Use typically trailing braces everywhere (if, else, functions, structures, typedefs, class definitions, etc.)

if (x) 
{
    //code
}

The else statement starts on new line after the last closing brace.

if (x) 
{
    //code
} 
else 
{
    //code
}

Null and false[edit | edit source]

In C++, the null pointer value should be written as nullptr. In C, it should be written as NULL.

Negation operator should not be used in its short form :

if (!cond)         // error-prone
if (cond == false) // better
if (not cond)      // better (alternative keyword, recommended way)

Floating point literals[edit | edit source]

Unless required in order to force floating point math, do not append .0, .f and .0f to floating point literals.

const double duration = 60;

void setDiameter(float diameter)
{
    radius = diameter / 2;
}

setDiameter(10);

const int framesPerSecond = 12;
double frameDuration = 1.0 / framesPerSecond;

Names[edit | edit source]

Function names start with an upper case:

void Function(void);

In multi-word function names each word starts with an upper case, including all letters in an acronym:

void ThisFunctionDoesSomething(void);
void HTMLDocument;

Variable names start with a lower case character.

float x;

In multi-word variable names the first word starts with a lower case character and each successive word starts with an upper case.

float maxDistanceFromPlane;

Names of recursive functions end with "_r"

void WalkBSP_r( int node );

Defined names use all upper case characters. Multiple words are separated with an underscore.

#define SIDE_FRONT      0

Use full words, except in the rare case where an abbreviation would be more canonical and easier to understand.

size_t characterSize;
size_t length;
short tabIndex; // more canonical

Data members in C++ classes should be private. Static data members should be prefixed by “s_”. Other data members should be prefixed by “m_”.

class String 
{
public:
    ...

private:
    short m_length;
};

Use ‘const’ as much as possible. Use:

const int *p;        // pointer to const int
int * const p;       // const pointer to int
const int * const p; // const pointer to const int

Same true for variables that will not be changed after initialization.

Don’t use:

int const *p;

Precede boolean values with words like “is” and “did”.

bool isValid;
bool didSendData;

Precede getters that return values through out arguments with the word “get”.

void getInlineBoxAndOffset(InlineBox*&, int& caretOffset) const;

Use descriptive verbs in function names.

bool convertToASCII(short*, size_t);

Prefer const to #define. Prefer inline functions to macros.

Macros that expand to function calls or other non-constant computation: these should be named like functions, and should have parentheses at the end, even if they take no arguments (with the exception of some special macros like ASSERT). Note that usually it is preferable to use an inline function in such cases instead of a macro.

#define, #ifdef “header guards” should be named exactly the same as the file (including case), replacing the . with a _.

// mainwindowsnogui.h
#ifndef MAINWINDOWSNOGUI_H
#define MAINWINDOWSNOGUI_H

For suppressing compiler warnings about unused parameters in code use Q_UNUSED() macros.

void Foo(int aParameter) 
{
    Q_UNUSED(aParameter)
}

Other Punctuation[edit | edit source]

Constructors for C++ classes should initialize all of their members using C++ initializer syntax. Each member (and superclass) should be indented on a separate line, with the colon or comma preceding the member on that line.

MyClass::MyClass(Document* document)
    : MySuperClass()
    , m_myMember(0)
    , m_document(document)
{
}

MyOtherClass::MyOtherClass()
    : MySuperClass()
{
}

Prefer index over iterator in Vector iterations for terse, easier-to-read code. Right:

for (auto& frameView : frameViews)
        frameView->updateLayoutAndStyleIfNeededRecursive();

OK:

unsigned frameViewsCount = frameViews.size();
for (unsigned i = 0; i < frameViewsCount; ++i)
    frameViews[i]->updateLayoutAndStyleIfNeededRecursive();

Classes[edit | edit source]

Class names start with "V" and each successive word starts with an upper case.

class VArc;

Class variables have the same naming convention as variables.

class VArc 
{
    qreal   f1;
    QString formulaF1;
    qreal   f2;
    QString formulaF2;
    qreal   radius;
    QString formulaRadius;
    VPointF center;
}

Class methods have the same naming convention as functions.

class VArc 
{
    QPointF CutArc (const qreal &length, VArc &arc1, VArc &arc2) const;
}

Indent the names of class variables and class methods to make nice columns. The variable type or method return type is in the first column and the variable name or method name is in the second column.

class VVec3 
{
    float         x;
    float         y;
    float         z;
    float         Length(void) const;
    const float * ToFloatPtr(void) const;
}

The * of the pointer is in the first column because it improves readability when considered part of the type.

Ordering of class variables and methods should be as follows:

  1. list of friend classes
  2. public variables
  3. public methods
  4. protected variables
  5. protected methods
  6. private variables
  7. private methods

This allows the public interface to be easily found at the beginning of the class.

Always make class methods ‘const’ when they do not modify any class variables.

Avoid use of ‘const_cast’. When object is needed to be modified, but only const versions are accessible, create a function that clearly gives an editable version of the object. This keeps the control of the ‘const-ness’ in the hands of the object and not the user.

Function overloading should be avoided in most cases. For example, instead of:

const idAnim *  GetAnim( int index ) const;
const idAnim *  GetAnim( const char *name ) const;
const idAnim *  GetAnim( float randomDiversity ) const;

Use:

const idAnim *  GetAnimByIndex( int index ) const;
const idAnim *  GetAnimByName( const char *name ) const;
const idAnim *  GetRandomAnim( float randomDiversity ) const;

Inline member functions define outside the class:

class Foo 
{
public:
    void method(); // best practice: don't put the inline keyword here
    ...
};

inline void Foo::method() // best practice: put the inline keyword here
{ 
    // code 
}

Note. Don't make virtual methods inline. See Clang warning -Wweak-vtables. Discusion on StackOverflow.

File names[edit | edit source]

Each class should be in a separate source file unless it makes sense to group several smaller classes. The file name should be the same as the name of the class with the "V" prefix.

class VArc;

files:

varc.cpp
varc.h