Skip to content

Inkscape

draw freely
最新の安定版: 0.48.4 今すぐダウンロード
Open Source Scalable Vector Graphics Editor
 

Inkscape Coding Style Guidelines

For discussion, please see Coding Style in Wiki.

Indention

We have decided to use 4 spaces as a tab for the project.

Files should include a modeline specifying the tab stops and indentation character specified by the standard.

public/protected/private declarations should be indented flush with the enclosing block's parent; for example:

 class Fleep {
 public:
    ...
 };

Labels and case statements should be fully indented (however, do not use goto unless you can articulate clearly and defensibly why you ought not to use it):

 void gromzala(int a)
 {
    ...
    somelabel:
    ...
    goto somelabel;
    ...
 }

 switch (fogo) {
    case ROMPH: {
       ...
       break;
    }
    case OOGA: {
       ...
       break;
    }
    default: {
       ...
    }
 }

Case statements should always have blocks attached.

Vertical Spacing

Don't collapse statements to single lines.

Inserting blank before/after a chunk of code can be useful for indicating a conceptual grouping.

Spacing

Examples:

 
 func(a, b);

 if (var) {
    ...
 }

 if (func(a, b)) {
    ...
 }

 if ( a != b ) {
    ...
 }

 for ( a = 0 ; a < b ; a++ ) {
    ...
 }

 while (!( a + b )) {
    ...
 }

 var = ( a | b ) & c;

 func(( a | b ), c);

 var = (int)( a + b );

 var = array[func(a, b)];

 func(array[a + b], c);

 return a + b;

 return ( a ? b : c );

Single variable per declaration.

Space between a type name/qualifier and pointer/reference sigil

Placement of const

Although in the past it has been common to place const' at the beginning of they type whenever C/C++ allows, this has led to experienced programmers misunderstanding int * const *p': people wrongly think it means that p is a constant pointer, when in fact p is a non-constant pointer to const pointers to non-const int's.

Consequently, we will switch to consistently placing the const after what it modifies: just as C/C++ leaves us no choice but to write int * const for a const pointer to (non-const) int, for consistency we also write int const for a const int.

Wrapping

On whether the operator goes at the end of the broken line or the beginning of the continuation:

     ( ( ( foodlesplork()
           && bartlecapple() )
         == ( fork < spoon ) )
       && ( ( cat + mouse < dog * rat )
            || eats(cat, mouse) )
       && !on_fire(house) )

is easier to parse than

     ( ( ( foodlesplork() &&
           bartlecapple() ) ==
         ( fork < spoon ) ) &&
       ( ( cat + mouse < dog * rat ) ||
         eats(cat, mouse) ) &&
       !on_fire(house) )

In cases where the precedence is easier to see without help, putting the operator at the end of the line can make it easier to see the similarities & differences between the operands by having them line up vertically:

    ( ( foo.fork  == bar.fork )  &&
      ( foo.spoon == bar.spoon ) &&
      ( foo.knife == bar.knife ) )

The above still uses the general principle of using extra whitespace to assist distinguishing the precedence of == and &&. This works well in the above example (with multiple lines ending in the same operator), though in other cases the extra space can make it harder to read.

The Preprocessor

DO NOT USE #ifdef UNLESS ABSOLUTELY NECESSARY. It leads to code rot as the surrounding code is changed, but the disabled code is not updated.

If you must disable a section of code temporarily, use plain "if" if at all possible. That will ensure that the code is still checked by the compiler, even though it will not be part of the resulting binary (the compiler will optimize out dead code chunks).

Also, never EVER do this:

 #ifdef SOMETHING
   some code
 #else
   some code (only slightly different)
 #endif

Often, fixes made to one piece of code will be missed in the other, and the two pieces of code may drift apart, introduced or unfixed bugs unnoticed for months...

If you do have to use #ifdef for something, absolutely try to minimize the amount of code within it. Make the remaining code as generic and portable as possible.

Declarations & Definitions

Use standard function declarations and definition all on a single line.

Braces

Compact braces should be used under normal circumstances. For example:

 if (flamoba) {
    ...
 } else {
    ...
 }

However, if the leading if/while/for expression spans more than one line, then the brace should be on a line by itself, in order to make clearer which lines are part of the expression and which lines are part of the block.

[This multi-line exception is particularly important if we choose an indentation quantum of 4--5 spaces, and not very important at all if the indentation quantum is 2-3 spaces -- in which case the expression continuation will already be more indented than the lines of the block.]

Example

 if ( grarzbo(mof, glorble(gronk), fofo, obo,
              fronk, bleeb)  &&
      grarzbo(fom, 42, 0, 0, 0, 0) )
 {
    ...
 } else {
    ...
 }

Brace goes on separate line for function definitions, to placate the parser used by add-change-log-entry.

Not required by function-menu, so perhaps we could fix the add-change-log-entry parser by copying from that used by function-menu.

Block statements should have braces when possible.

Naming by Example

 NamespaceName
 ClassName
 CONSTANT_NAME

 publicMemberFunctionName
 _protectedMemberFunctionName
 _privateMemberFunctionName

 public_static_member_function_name
 _protected_static_member_function_name
 _private_static_member_function_name

 _member_name
 function_name
 variable_name

C++

Class Design Consistency

Class definitions: at most one public: block, followed by at most one protected: block, followed by at most one private: block.

Namespace blocks do not introduce an additonal indention level

Always define default, private, un-defined copy ctor and operator = . As a rule, all C++ classes should have an explicit copy constructor and assignment operator (operator =). Instead of defaulting to the standard one, any classes that don't already have them should have the two declared in the private: section of the class, but never actually have those functions defined.

class Foo {
   ...
private:
    Foo(const Foo& other); // no copy
    void operator=(const Foo& other); // no assign
};

When a class has a destructor, always make it virtual. Just to be on the safe side. For an explanation, please see "When should my destructor be virtual?" on C++ FAQ Lite.

class Foo {
 ...
    virtual ~Foo();
 ...
};

Non-trivial inline methods (i.e. other than one-line trivial mutators/accessors) should be placed outside the class definition (though still in the header file), e.g.:

 class Fubo {
 public:
    void torfle(int morp);
 };

 inline void Fubo::torfle(int morp)
 {
    ...
 }

Namespace using

Templates

Template keywords should get their own line, so the actual function or class name is easy to find next to the mess of angle brackets.

For example:

 template <class T>
 void pobi(T &ubba)
 {
    ...
 }

or, in the case of a template specialization:

 template<>
 class Roga<Florm> {
    ...
 }