[flang] C++ usage and style guide summary.

Original-commit: flang-compiler/f18@2cf1be7b05
This commit is contained in:
peter klausler 2018-02-05 10:46:32 -08:00
parent 55fe4d2af5
commit ac12232e68
1 changed files with 137 additions and 0 deletions

137
flang/c++style.txt Executable file
View File

@ -0,0 +1,137 @@
In brief:
- Where LLVM's C++ style guide is clear, follow it.
- Otherwise, where a clear precedent exists in the project, follow it.
- Otherwise, where a good public C++ style guide is relevant and clear,
follow it. (Google's is pretty good and comes with lots of justifications
for its rules.)
Some particular points:
File names should use dashes, not underscores. C++ sources have the
extension ".cc", not ".C" or ".cpp" or ".cxx". Don't create needless
source directory hierarchies.
C++ names that correspond to STL names should look like those STL names
(e.g., clear() and size() member functions).
Non-public data members should be named with leading miniscule (lower-case)
letters, internal camelCase capitalization, and a trailing underscore,
e.g. "DoubleEntryBookkeepingSystem myLedger_;". POD structures with
only public data members shouldn't use trailing underscores, since they
don't have class functions in which data members need to be distinguishable.
Define only POD structures with "struct". Use "foo_" and "Bar(x)" in
non-static member functions, not "this->foo_" and "this->Bar(x)".
Accessor member functions are named with the non-public data member's name,
less the trailing underscore. Mutator member functions are named "set_..."
and should return *this. Don't define accessors or mutators needlessly.
Other class functions should be named with leading capital letters,
CamelCase, and no underscores, and, like all functions, should be based
on imperative verbs, e.g. "HaltAndCatchFire()".
Header files should be idempotent:
#ifndef FORTRAN_headername_H_
#define FORTRAN_headername_H_
// code
#endif // FORTRAN_headername_H_
Use // for all comments except for short /*notes*/ within statements.
When // follows code on a line, precede it with two spaces. Comments
should matter. Assume that the reader knows current C++ at least as
well as you do and avoid distracting her by calling out usage of new
features in comments.
Use {braced initializers} in all circumstances where they work, including
default data member initialization. They inhibit implicit truncation.
Don't use "= expr" initialization just to effect implicit truncation;
prefer an explicit static_cast<>.
Avoid unsigned types apart from size_t, which must be used with care.
When int just obviously works, just use int. When you need something bigger
than int, use std::int64_t.
Never throw or catch exceptions.
Never use run-time type information or dynamic_cast<>.
Never declare static data that executes a constructor.
Indent with two spaces, except for public:/protected:/private: in classes,
which are indented by one. Never use more than 80 characters per source line.
Don't use tabs. Don't try to make columns of variable names or comments
align vertically -- they are maintenance problems. Don't indent the bodies
of namespaces, even when nested.
Define accessor and mutator member functions (implicitly) inline in the
class, after constructors and assignments. Don't needlessly define
(implicit) inline member functions in classes unless they really solve a
performance problem. Try to make class definitions in headers concise
specifications of interfaces, at least to the degree that C++ allows.
#include header that a project header or source file actually uses directly.
(Exception: when foo.cc starts with #include "foo.h", and foo.h includes
bar.h in order to define the interface to foo, you don't have to redundantly
include bar.h in foo.cc.) Order the #include directives for foo.cc as
#include "foo.h" // this module's interface comes first
#include "armadillo.h" // other modules in this project, alphabetically
#include "zebra.h"
#include <algorithm> // C++ standard headers, alphabetically
#include <vector>
#include <sys/types.h> // C headers, alphabetically
Put templates into headers when they need to be there.
Prefer static functions to functions in anonymous namespaces in source files.
Use namespaces to avoid conflicts with client code. Use one top-level project
namespace. Don't introduce needless nested namespaces within a project
when names don't conflict or better solutions exist. Never use
"using namespace ...;", especially not "using namespace std;". Access
STL entities with names like "std::unique_ptr<>", without a leading "::".
Don't waste space on the screen with needless blank lines or elaborate block
commentary (lines of dashes, boxes of asterisks, &c.). Write code so as to be
easily read and understood with a minimum of scrolling. Function result types
go on the same line as the function and argument names, if they can all fit
in 80 columns.
It is fine to use short names for local variables with limited scopes,
especially when you can declare them directly in the for()/while()/if()
condition. Otherwise, prefer complete English words to abbreviations
when creating names.
Use "auto" judiciously. When the type of a local variable is known and
easy to type, be explicit rather than using auto.
Use move semantics and smart pointers to make dynamic memory ownership
clear. Consider reworking any code that uses malloc() or a (non-placement)
operator new. When copy constructors and copy assignment are not necessary,
and move constructors/assignment is present, don't declare them and they
will be implicitly "= delete;". When neither copy nor move constructors
or assignments should exist for a class, explicitly "= delete;" all of them.
Use references for const arguments; prefer const references to values for
all but small types that are trivially copyable (e.g., int). Use non-const
pointers for output arguments. Put output arguments last (pace the standard
C library conventions for memcpy() & al.).
Prefer "template<typename T>" to "template<class T>".
Prefer "enum class" to plain "enum" wherever enum class will work.
Use constexpr and const generously.
Always wrap the bodies of if(), else, while(), for(), do, &c. with braces,
even when the body is a single statement or empty. The opening "{" goes on
the end of the line, not on the next line. Functions also put the opening
"{" after the formal arguments or new-style result type, not on the next
line. Use "{}" for empty inline constructors and destructors in classes.
Don't use dynamic solutions to solve problems that can be solved at
build time; don't solve build time problems by writing programs that
produce source code when macros and templates suffice; don't write macros
when templates suffice. Templates are statically typed, checked by the
compiler, and visible to debuggers.
When a switch() does not cover all case values explicitly, it should
contains either a "default:;" at its end or a "default:" label that
crashes.