Purpose of this style guide is to encourage use of common coding practices within the ESP-IDF.
Style guide is a set of rules which are aimed to help create readable, maintainable, and robust code. By writing code which looks the same way across the code base we help others read and comprehend the code. By using same conventions for spaces and newlines we reduce chances that future changes will produce huge unreadable diffs. By following common patterns for module structure and by using language features consistently we help others understand code behavior.
We try to keep rules simple enough, which means that they can not cover all potential cases. In some cases one has to bend these simple rules to achieve readability, maintainability, or robustness.
When doing modifications to third-party code used in ESP-IDF, follow the way that particular project is written. That will help propose useful changes for merging into upstream project.
Note however that if someone goes to add new line with a longer identifier as first argument (e.g. ``PIN_CAM_VSYNC``), it will not fit. So other lines would have to be realigned, adding meaningless changes to the commit.
Therefore, use horizontal alignment sparingly, especially if you expect new lines to be added to the list later.
Never use TAB characters for horizontal alignment.
Never add trailing whitespace at the end of the line.
Use ``//`` for single line comments. For multi-line comments it is okay to use either ``//`` on each line or a ``/* */`` block.
Although not directly related to formatting, here are a few notes about using comments effectively.
- Don't use single comments to disable some functionality::
void init_something()
{
setup_dma();
// load_resources(); // WHY is this thing commented, asks the reader?
start_timer();
}
- If some code is no longer required, remove it completely. If you need it you can always look it up in git history of this file. If you disable some call because of temporary reasons, with an intention to restore it in the future, add explanation on the adjacent line::
void init_something()
{
setup_dma();
// TODO: we should load resources here, but loader is not fully integrated yet.
// load_resources();
start_timer();
}
- Same goes for ``#if 0 ... #endif`` blocks. Remove code block completely if it is not used. Otherwise, add comment explaining why the block is disabled. Don't use ``#if 0 ... #endif`` or comments to store code snippets which you may need in the future.
- Don't add trivial comments about authorship and change date. You can always look up who modified any given line using git. E.g. this comment adds clutter to the code without adding any useful information::
Commits should only contain files with LF (Unix style) endings.
Windows users can configure git to check out CRLF (Windows style) endings locally and commit LF endings by setting the ``core.autocrlf`` setting. `Github has a document about setting this option <github-line-endings>`. However because MSYS2 uses Unix-style line endings, it is often easier to configure your text editor to use LF (Unix style) endings when editing ESP-IDF source files.
If you accidentally have some commits in your branch that add LF endings, you can convert them to Unix by running this command in an MSYS2 or Unix terminal (change directory to the IDF working directory and check the correct branch is currently checked out, beforehand)::
git rebase --exec 'git diff-tree --no-commit-id --name-only -r HEAD | xargs dos2unix && git commit -a --amend --no-edit --allow-empty' master
(Note that this line rebases on master, change the branch name at the end to rebase on another branch.)
For updating a single commit, it's possible to run ``dos2unix FILENAME`` and then run ``git commit --amend``
You can use ``astyle`` program to format your code according to the above recommendations.
If you are writing a file from scratch, or doing a complete rewrite, feel free to re-format the entire file. If you are changing a small portion of file, don't re-format the code you didn't change. This will help others when they review your changes.
The same rules as for C apply. Where they are not enough, apply the following rules.
File Naming
^^^^^^^^^^^^
C++ Header files have the extension ``.h``. C++ source files have the extension ``.cpp``, which is important for the compiler to distiguish them from normal C source files.
Naming
^^^^^^
***Class and struct** names shall be written in ``CamelCase`` with a capital letter as beginning. Member variables and methods shall be in ``snake_case``.
***Namespaces** shall be in lower ``snake_case``.
***Templates** are specified in the line above the function declaration.
Member Order in Classes
^^^^^^^^^^^^^^^^^^^^^^^
First put the public members, then the protected, then private ones. Omit public, protected or private sections without any members.
Spacing
^^^^^^^
* Don't indent inside namespaces.
* Put ``public``, ``protected`` and ``private`` labels at the same indentation level as the corresponding ``class`` label.
Simple Example
^^^^^^^^^^^^^^^
::
// file spaceship.h
#ifndef SPACESHIP_H_
#define SPACESHIP_H_
#include <cstdlib>
namespace spaceships {
class SpaceShip {
public:
SpaceShip(size_t crew);
size_t get_crew_size() const;
private:
const size_t crew;
};
class SpaceShuttle : public SpaceShip {
public:
SpaceShuttle();
};
class Sojuz : public SpaceShip {
public:
Sojuz();
};
template <typename T>
class CargoShip {
public:
CargoShip(const T &cargo);
private:
T cargo;
};
} // namespace spaceships
#endif // SPACESHIP_H_
// file spaceship.cpp
#include "spaceship.h"
namespace spaceships {
// Putting the curly braces in the same line for constructors is OK if it only initializes
EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems.
For more information, see `EditorConfig <http://editorconfig.org>`_ Website.
- Any variable or function which is only used in a single source file should be declared ``static``.
- Public names (non-static variables and functions) should be namespaced with a per-component or per-unit prefix, to avoid naming collisions. ie ``esp_vfs_register()`` or ``esp_console_run()``. Starting the prefix with ``esp_`` for Espressif-specific names is optional, but should be consistent with any other names in the same component.
- Static variables should be prefixed with ``s_`` for easy identification. For example, ``static bool s_invert``.
- Avoid unnecessary abbreviations (ie shortening ``data`` to ``dat``), unless the resulting name would otherwise be very long.