Skip to content

Source code formatting conventions

John W. Peterson edited this page Jan 5, 2016 · 35 revisions

The contrib/bin/reindent.sh script is provided to automatically control the amount and type of indentation used in libMesh source files. It isn't perfect, but it's pretty good, and if you run this script on the files you've modified before submitting them, we won't have to run it on them later, artificially changing line ownership statistics.

Note: The current codebase does not exactly follow all the conventions below! We try to fix things as we come across them in the process of doing other work, but it's very likely a cursory examination will uncover non-compliant code.

Whitespace/editor

  • Tab characters are not allowed in indentation, use only spaces. Most editors have a way of enforcing this convention, for instance in Emacs, add the following to your .emacs file:
(setq-default indent-tabs-mode nil)
  • No trailing whitespace is allowed. Again, most editors have a way of removing trailing whitespace either manually (Emacs: M-x delete-trailing-whitespace) or automatically, again in Emacs:
(add-hook 'c-mode-hook
  (lambda () (add-to-list 'write-file-functions 'delete-trailing-whitespace)))
  • Every file should end with a single newline. That is, in the output of git diff, you should not see:
\ No newline at end of file
  • There is no maximum (or minimum) allowed line length, but around 125 characters is probably pushing the limits of readability. Use your best judgement, shorter is not necessarily always better either.

Naming

  • Class names begin with a capital letter and use camelcase, e.g. MeshBase, FEMFunction, etc.

  • Functions names are lowercase and use underscores to separate the words, e.g. get_boundary_info(), make_node_proc_ids_parallel_consistent().

  • Variable names also use the lowercase/underscore convention. Private and protected members of classes are prefixed with a leading underscore, e.g. unsigned int _foo;.

Documentation

  • Use Doxygen-style comment blocks, including \author and \date directives if desired, at the top of classes. Use C++ style comments for everything else.
/**
 * This class is ground-breaking.
 * 
 * \author Bob
 * \date 2015
 */
class BigBertha
{
public:
  // Constructor.  Breaks ground.
  BigBertha();
};

Spacing and indentation

  • Leave one space on either side of the * or & character in pointer and reference declarations, respectively. Do not leave a space when dereferencing or taking the address of a variable.
unsigned int x = 42;
unsigned int * px = &x;
unsigned int & rx = *px;
  • Indent streaming print statements on the stream injection (<<) operator. (This convention applies to long lines only, multiple << operators on a single, short line is also OK.)
oss << std::fixed
    << std::setprecision(4)
    << std::setw(tot_time_col_width)
    << std::left
    << summed_total_time;
  • All libMesh classes are declared in namespace libMesh. Indent zero spaces in namespaces, and two spaces in classes, except for access control (public, protected, private) keywords.
namespace libMesh
{

class Foo
{
public:
  Foo (unsigned int bar);
};

}
  • Leave at least three blank lines between function body definitions in .C files. This makes it easier to see where one function body ends and the next begins at a quick glance.
void BigBertha::drill()
{
  if (!working)
    backup();
}



void BigBertha::backup()
{
  libmesh_error();
}

Function prototypes

  • Template declarations should appear on a separate line.
  • The function parameter list should begin on the same line as the function name.
  • Return type may be on a separate line if desired.
  • One space between function name and opening parenthesis, no space after opening parenthesis.
  • For functions with long parameter lists, use one line per parameter (otherwise all on one line).
  • Indent each parameter to the beginning of the parameter on previous line.
template<typename OutputShape>
UniquePtr<FEGenericBase<OutputShape> >
build_new_fe (const FEGenericBase<OutputShape> * fe,
              const Point & p,
              const Real tolerance = TOLERANCE) const;
  • One space after commas in single-line function parameter lists:
void foo(int bar, float baz, char bob);

"for" loops

  • Single-line for loops should not use curly braces.
  • One space between the keyword and opening parenthesis.
  • Start curly braces on a new line (similarly for if and while loops).
  • Indent curly brace two spaces. (This indentation pattern reflects the current behavior of reindent.sh, but it may be changed at some point in the future.)
  • Put spaces after semi-colons in the for-loop declaration.
for (unsigned int i=1; i<=N; ++i)
  {
    sum += i;
    prod *= i;   
  }