C++ Programming Style Guidelines

  • We should move to C++14 standard and remove deprecated features
  • Source Code Beautifier : Uncrustify (GreenSocs template : soon)
  • We want consistency code, easy to write, easy to read, easy to use.

Naming

Variable Names

Constant Names

Function Names

  • We use lowerCamelCase for function names.
  • Leave spaces around overloaded operators, e.g. operator + (...); rather than operator+(...);

Namespace Names

Strings

  • Strings used in log and error messages should end without a period.

Breaks

  • Break before braces on function, class, struct and union definitions.

Indentation

  • Soft-tab : 4 spaces

Types

Char

char

Integer

We should try to use as most as possible standard integer types defined in <cstdint> (since C++11) : int8_t, int32_t, uint32_t...

Float

float, double, and long double

String

std::string

Conditions

  • Use attached braces: The opening brace goes on the same line as the start of the statement. If the closing brace is followed by another keyword, it goes into the same line as well:
int a = 3;
if(a == 1) {
    // instructions
} else if(a != 3) {
    // instructions
} else {
    // instructions
}
  • Always use a single space after a keyword and before a curly brace:
// NOT OK
if(a==2){
    //...
}

// OK
if(a == 2) {
    //...
}

  • No space before and after parenthesis.
  • Space before and after condition operator.
  • Do not put multiple statements on one line
  • Use curly braces only when the body of a conditional statement contains more than one line
  • By extension, use a new line for the body of a control flow statement:
// NOT OK
if (foo) bar();

// OK
if(foo)
    bar();
  • Exception 1: Use braces also if the parent statement covers several lines / wraps:
// OK
if(data.isEmpty() || !isValid()
                  || !enable) {
    return false;
}
  • Exception 2: Brace symmetry: Use braces also in if-then-else blocks where either the if-code or the else-code covers several lines:
// NOT OK
if(data.isEmpty())
    return false;
else 
{
    printf("%s", "GreenSocs");
    ++it;
}

// OK
if(data.isEmpty()) {
    return false;
} else {
    printf("%s", "GreenSocs");
    ++it;
}

// NOT OK
if (a)
    if (b)
        ...
    else
        ...

// OK
if (a) {
    if (b)
        ...
    else
        ...
}
  • Use parentheses to group expressions:
// NOT OK
if(a && b || c)

// OK
if((a && b) || c)

// NOT OK
a + b & c

// OK
(a + b) & c

Declaring variables

  • Declare each variable on a separate line
  • Avoid short or meaningless names (e.g. “a”, “rbarr”, “foo”)
  • Single character variable names are only okay for counters and temporaries, where the purpose of the variable is obvious
// NOT OK
int a, b;
char *c, *d;

// OK
sc_event myEvent;
sc_event anotherEvent;
char *nameOfThis;
char *nameOfThat;
  • Avoid abbreviations
// NOT OK
sc_evt myEvt;
int cntr;

// OK
sc_event myEvent;
int counter;
  • For pointers or references, always use a single space ‘’ or ‘&’ and the variable name, but no space between the ‘’ or ‘&’ and the type:
char* x;
const GreenReg &myReg;
const char* const y = "hello";
  • Surround binary operators with spaces
  • No space after a cast
  • Avoid C-style casts when possible:
// NOT OK
char* virtualMemory = (char* ) malloc(data.size());

// OK
char * virtualMemory = reinterpret_cast<char *>(malloc(data.size()));

Class

/*
 * @file classname.h
 * @author Guillaume Delbergue <guillaume.delbergue@greensocs.com>
 * @date May, 2015
 * @copyright Copyright (C) 2015, GreenSocs Ltd.
 *
 * @brief Definition of my ClassName
 */

// ... (somewhere else, like greenreg.h)
#DEFINE GREENREG_BEGIN_NAMESPACE namespace gs::reg {
#DEFINE GREENREG_END_NAMESPACE }
// ...

GREENREG_BEGIN_NAMESPACE

class ClassName /* upper camel case */ { 
public:
    std::string getMyVar(); // lower camel case

protected:
    std::string myVar; // lower camel case

private:
    uint32_t anotherPrivateVar; // lower camel case
}

GREENREG_END_NAMESPACE

Name

  • Use upper case letters as word separators, lower case for the rest of a word
  • First character in a name is upper case
  • No underbars ('_')

File

  • One class per file
  • ClassName filename must be classname.cpp

Inheritance

class ClassName : public Toto, public Tata { 
// ...
}

Method

std::string ClassName ::getMyVar() 
{
    return this->myVar;
}

Headers

Extension

  • .hpp : C++ Headers
  • .h : C/C++ compatible or pure C Headers

#DEFINE

Use CLASSNAME_H

#ifndef GREENREG_H
#define GREENREG_H

...

#endif  // GREENREG_H

Names and Order of Includes

All of a project's header files should be listed as descendants of the project's source directory without use of UNIX directory shortcuts . (the current directory) or .. (the parent directory). For example :

  1. C system files
  2. C++ system files
  3. Other libraries .h files
  4. Project .h files
#include <sys/types.h>
#include <unistd.h>
#include <hash_map>
#include <vector>

#include "greenlib/gsscapidetection.h"
#include "greenreg/register.h"
#include "greenreg/registers/bitrange.h"

Comments

  • End each sentence with a period.
  • At most 70 characters per line in comments.
  • For trailing comments, leave one space.

Simple

// Lorem ipsum dolor sit amet, consetetur soliuj

or (less common)

/* Lorem ipsum dolor sit amet, consetetur soliuj */

Multiple lines

/*
 * Lorem ipsum dolor sit amet, consetetur soliuj
 * m dolor sit amet, consetetur soliuj
 */  

Doxygen

/**
 * Lorem ipsum dolor sit amet, consetetur s
 *
 * @param amet nsetetur 
 * @param fezfz voluptua
 *
 * @return afez fezfezfez fez f
 */
/** 
 * An enum type. 
 * The documentation block cannot be put after the enum! 
 */
enum EnumType {
    int EVal1,     /**< enum value 1 */
    int EVal2      /**< enum value 2 */
};

TODO

Editor

CI

Sources :