1 <!--===- docs/C++style.md
3 Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 See https://llvm.org/LICENSE.txt for license information.
5 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 # Flang C++ Style Guide
17 This document captures the style guide rules that are followed in the Flang codebase.
22 on all C++ source and header files before
23 every merge to main. All code layout should be determined
24 by means of clang-format.
25 * Where a clear precedent exists in the project, follow it.
26 * Otherwise, where [LLVM's C++ style guide](https://llvm.org/docs/CodingStandards.html#style-issues)
27 is clear on usage, follow it.
28 * Otherwise, where a good public C++ style guide is relevant and clear,
29 follow it. [Google's](https://google.github.io/styleguide/cppguide.html)
30 is pretty good and comes with lots of justifications for its rules.
31 * Reasonable exceptions to these guidelines can be made.
32 * Be aware of some workarounds for known issues in older C++ compilers that should
33 still be able to compile f18. They are listed at the end of this document.
37 Use serial commas in comments, error messages, and documentation
38 unless they introduce ambiguity.
41 1. Messages should be a single sentence with few exceptions.
42 1. Fortran keywords should appear in upper case.
43 1. Names from the program appear in single quotes.
44 1. Messages should start with a capital letter.
45 1. Messages should not end with a period.
48 1. File names should use dashes, not underscores. C++ sources have the
49 extension ".cpp", not ".C" or ".cc" or ".cxx". Don't create needless
50 source directory hierarchies.
51 1. Header files should be idempotent. Use the usual technique:
53 #ifndef FORTRAN_header_H_
54 #define FORTRAN_header_H_
56 #endif // FORTRAN_header_H_
58 1. `#include` every header defining an entity that your project header or source
59 file actually uses directly. (Exception: when foo.cpp starts, as it should,
60 with `#include "foo.h"`, and foo.h includes bar.h in order to define the
61 interface to the module foo, you don't have to redundantly `#include "bar.h"`
63 1. In the source file "foo.cpp", put its corresponding `#include "foo.h"`
64 first in the sequence of inclusions.
65 Then `#include` other project headers in alphabetic order; then C++ standard
66 headers, also alphabetically; then C and system headers.
67 1. Don't use `#include <iostream>`. If you need it for temporary debugging,
68 remove the inclusion before committing.
71 1. C++ names that correspond to well-known interfaces from the STL, LLVM,
73 can and should look like their models when the reader can safely assume that
74 they mean the same thing -- e.g., `clear()` and `size()` member functions
75 in a class that implements an STL-ish container.
76 Fortran intrinsic function names are conventionally in ALL CAPS.
77 1. Non-public data members should be named with leading miniscule (lower-case)
78 letters, internal camelCase capitalization, and a trailing underscore,
79 e.g. `DoubleEntryBookkeepingSystem myLedger_;`. POD structures with
80 only public data members shouldn't use trailing underscores, since they
81 don't have class functions from which data members need to be distinguishable.
82 1. Accessor member functions are named with the non-public data member's name,
83 less the trailing underscore. Mutator member functions are named `set_...`
84 and should return `*this`. Don't define accessors or mutators needlessly.
85 1. Other class functions should be named with leading capital letters,
86 CamelCase, and no underscores, and, like all functions, should be based
87 on imperative verbs, e.g. `HaltAndCatchFire()`.
88 1. It is fine to use short names for local variables with limited scopes,
89 especially when you can declare them directly in a `for()`/`while()`/`if()`
90 condition. Otherwise, prefer complete English words to abbreviations
94 1. Use `//` for all comments except for short `/*notes*/` within expressions.
95 1. When `//` follows code on a line, precede it with two spaces.
96 1. Comments should matter. Assume that the reader knows current C++ at least as
97 well as you do and avoid distracting her by calling out usage of new
101 Always run `clang-format` on your changes before committing code. LLVM
102 has a `git-clang-format` script to facilitate running clang-format only
103 on the lines that have changed.
105 Here's what you can expect to see `clang-format` do:
106 1. Indent with two spaces.
107 1. Don't indent public:, protected:, and private:
108 accessibility labels.
109 1. Never use more than 80 characters per source line.
111 1. Don't indent the bodies of namespaces, even when nested.
112 1. Function result types go on the same line as the function and argument
115 Don't try to make columns of variable names or comments
116 align vertically -- they are maintenance problems.
118 Always wrap the bodies of `if()`, `else`, `while()`, `for()`, `do`, &c.
119 with braces, even when the body is a single statement or empty. Note that this
120 diverges from the LLVM coding style. In parts of the codebase that make heavy
121 use of LLVM or MLIR APIs (e.g. the Lower and Optimizer libraries), use the
122 LLVM style instead. The
124 the end of the line, not on the next line. Functions also put the opening
125 `{` after the formal arguments or new-style result type, not on the next
126 line. Use `{}` for empty inline constructors and destructors in classes.
128 If any branch of an `if`/`else if`/`else` cascade ends with a return statement,
129 they all should, with the understanding that the cases are all unexceptional.
130 When testing for an error case that should cause an early return, do so with
131 an `if` that doesn't have a following `else`.
133 Don't waste space on the screen with needless blank lines or elaborate block
134 commentary (lines of dashes, boxes of asterisks, &c.). Write code so as to be
135 easily read and understood with a minimum of scrolling.
137 Avoid using assignments in controlling expressions of `if()` &c., even with
138 the idiom of wrapping them with extra parentheses.
140 In multi-element initializer lists (especially `common::visitors{...}`),
141 including a comma after the last element often causes `clang-format` to do
142 a better jobs of formatting.
145 Use *C++17*, unless some compiler to which we must be portable lacks a feature
148 1. Never throw or catch exceptions.
149 1. Never use run-time type information or `dynamic_cast<>`.
150 1. Never declare static data that executes a constructor.
151 (This is why `#include <iostream>` is contraindicated.)
152 1. Use `{braced initializers}` in all circumstances where they work, including
153 default data member initialization. They inhibit implicit truncation.
154 Don't use `= expr` initialization just to effect implicit truncation;
155 prefer an explicit `static_cast<>`.
156 With C++17, braced initializers work fine with `auto` too.
157 Sometimes, however, there are better alternatives to empty braces;
158 e.g., prefer `return std::nullopt;` to `return {};` to make it more clear
159 that the function's result type is a `std::optional<>`.
160 1. Avoid unsigned types apart from `size_t`, which must be used with care.
161 When `int` just obviously works, just use `int`. When you need something
162 bigger than `int`, use `std::int64_t` rather than `long` or `long long`.
163 1. Use namespaces to avoid conflicts with client code. Use one top-level
164 `Fortran` project namespace. Don't introduce needless nested namespaces within the
165 project when names don't conflict or better solutions exist. Never use
166 `using namespace ...;` outside test code; never use `using namespace std;`
167 anywhere. Access STL entities with names like `std::unique_ptr<>`,
168 without a leading `::`.
169 1. Prefer `static` functions over functions in anonymous namespaces in source files.
170 1. Use `auto` judiciously. When the type of a local variable is known,
171 monomorphic, and easy to type, be explicit rather than using `auto`.
172 Don't use `auto` functions unless the type of the result of an outlined member
173 function definition can be more clear due to its use of types declared in the
175 1. Use move semantics and smart pointers to make dynamic memory ownership
176 clear. Consider reworking any code that uses `malloc()` or a (non-placement)
178 See the section on Pointers below for some suggested options.
179 1. When defining argument types, use values when object semantics are
180 not required and the value is small and copyable without allocation
182 use `const` or rvalue references for larger values (e.g., `std::string`);
183 use `const` references to rather than pointers to immutable objects;
184 and use non-`const` references for mutable objects, including "output" arguments
185 when they can't be function results.
186 Put such output arguments last (_pace_ the standard C library conventions for `memcpy()` & al.).
187 1. Prefer `typename` to `class` in template argument declarations.
188 1. Prefer `enum class` to plain `enum` wherever `enum class` will work.
189 We have an `ENUM_CLASS` macro that helps capture the names of constants.
190 1. Use `constexpr` and `const` generously.
191 1. When a `switch()` statement's labels do not cover all possible case values
192 explicitly, it should contain either a `default:;` at its end or a
193 `default:` label that obviously crashes; we have a `CRASH_NO_CASE` macro
195 1. On the other hand, when a `switch()` statement really does cover all of
196 the values of an `enum class`, please insert a call to the `SWITCH_COVERS_ALL_CASES`
197 macro at the top of the block. This macro does the right thing for G++ and
198 clang to ensure that no warning is emitted when the cases are indeed all covered.
199 1. When using `std::optional` values, avoid unprotected access to their content.
200 This is usually by means of `x.has_value()` guarding execution of `*x`.
201 This is implicit when they are function results assigned to local variables
202 in `if`/`while` predicates.
203 When no presence test is obviously protecting a `*x` reference to the
204 contents, and it is assumed that the contents are present, validate that
205 assumption by using `x.value()` instead.
206 1. We use `c_str()` rather than `data()` when converting a `std::string`
207 to a `const char *` when the result is expected to be NUL-terminated.
208 1. Avoid explicit comparisions of pointers to `nullptr` and tests of
209 presence of `optional<>` values with `.has_value()` in the predicate
210 expressions of control flow statements, but prefer them to implicit
211 conversions to `bool` when initializing `bool` variables and arguments,
212 and to the use of the idiom `!!`.
215 1. Define POD structures with `struct`.
216 1. Don't use `this->` in (non-static) member functions, unless forced to
217 do so in a template member function.
218 1. Define accessor and mutator member functions (implicitly) inline in the
219 class, after constructors and assignments. Don't needlessly define
220 (implicit) inline member functions in classes unless they really solve a
222 1. Try to make class definitions in headers concise specifications of
223 interfaces, at least to the extent that C++ allows.
224 1. When copy constructors and copy assignment are not necessary,
225 and move constructors/assignment is present, don't declare them and they
226 will be implicitly deleted. When neither copy nor move constructors
227 or assignments should exist for a class, explicitly `=delete` all of them.
228 1. Make single-argument constructors (other than copy and move constructors)
229 'explicit' unless you really want to define an implicit conversion.
232 There are many -- perhaps too many -- means of indirect addressing
233 data in this project.
234 Some of these are standard C++ language and library features,
235 while others are local inventions in `lib/Common`:
236 * Bare pointers (`Foo *p`): these are obviously nullable, non-owning,
237 undefined when uninitialized, shallowly copyable, reassignable, and often
238 not the right abstraction to use in this project.
239 But they can be the right choice to represent an optional
240 non-owning reference, as in a function result.
241 Use the `DEREF()` macro to convert a pointer to a reference that isn't
242 already protected by an explicit test for null.
243 * References (`Foo &r`, `const Foo &r`): non-nullable, not owning,
244 shallowly copyable, and not reassignable.
245 References are great for invisible indirection to objects whose lifetimes are
246 broader than that of the reference.
247 Take care when initializing a reference with another reference to ensure
248 that a copy is not made because only one of the references is `const`;
249 this is a pernicious C++ language pitfall!
250 * Rvalue references (`Foo &&r`): These are non-nullable references
251 *with* ownership, and they are ubiquitously used for formal arguments
252 wherever appropriate.
253 * `std::reference_wrapper<>`: non-nullable, not owning, shallowly
254 copyable, and (unlike bare references) reassignable, so suitable for
255 use in STL containers and for data members in classes that need to be
256 copyable or assignable.
257 * `common::Reference<>`: like `std::reference_wrapper<>`, but also supports
258 move semantics, member access, and comparison for equality; suitable for use in
260 * `std::unique_ptr<>`: A nullable pointer with ownership, null by default,
261 not copyable, reassignable.
262 F18 has a helpful `Deleter<>` class template that makes `unique_ptr<>`
263 easier to use with forward-referenced data types.
264 * `std::shared_ptr<>`: A nullable pointer with shared ownership via reference
265 counting, null by default, shallowly copyable, reassignable, and slow.
266 * `Indirection<>`: A non-nullable pointer with ownership and
267 optional deep copy semantics; reassignable.
268 Often better than a reference (due to ownership) or `std::unique_ptr<>`
269 (due to non-nullability and copyability).
270 Can be wrapped in `std::optional<>` when nullability is required.
271 Usable with forward-referenced data types with some use of `extern template`
272 in headers and explicit template instantiation in source files.
273 * `CountedReference<>`: A nullable pointer with shared ownership via
274 reference counting, null by default, shallowly copyable, reassignable.
275 Safe to use *only* when the data are private to just one
277 Used sparingly in place of `std::shared_ptr<>` only when the overhead
278 of that standard feature is prohibitive.
282 | indirection | nullable | default null | owning | reassignable | copyable | undefined type ok? |
283 | ----------- | -------- | ------------ | ------ | ------------ | -------- | ------------------ |
284 | `*p` | yes | no | no | yes | shallowly | yes |
285 | `&r` | no | n/a | no | no | shallowly | yes |
286 | `&&r` | no | n/a | yes | no | shallowly | yes |
287 | `reference_wrapper<>` | no | n/a | no | yes | shallowly | yes |
288 | `Reference<>` | no | n/a | no | yes | shallowly | yes |
289 | `unique_ptr<>` | yes | yes | yes | yes | no | yes, with work |
290 | `shared_ptr<>` | yes | yes | yes | yes | shallowly | no |
291 | `Indirection<>` | no | n/a | yes | yes | optionally deeply | yes, with work |
292 | `CountedReference<>` | yes | yes | yes | yes | shallowly | no |
294 ### Overall design preferences
295 Don't use dynamic solutions to solve problems that can be solved at
296 build time; don't solve build time problems by writing programs that
297 produce source code when macros and templates suffice; don't write macros
298 when templates suffice. Templates are statically typed, checked by the
299 compiler, and are (or should be) visible to debuggers.
301 ### Exceptions to these guidelines
302 Reasonable exceptions will be allowed; these guidelines cannot anticipate
304 For example, names that come from other sources might be more clear if
305 their original spellings are preserved rather than mangled to conform
306 needlessly to the conventions here, as Google's C++ style guide does
307 in a way that leads to weirdly capitalized abbreviations in names
309 Consistency is one of many aspects in the pursuit of clarity,
310 but not an end in itself.
312 ## C++ compiler bug workarounds
313 Below is a list of workarounds for C++ compiler bugs met with f18 that, even
314 if the bugs are fixed in latest C++ compiler versions, need to be applied so
315 that all desired tool-chains can compile f18.
317 ### Explicitly move noncopyable local variable into optional results
319 The following code is legal C++ but fails to compile with the
320 default Ubuntu 18.04 g++ compiler (7.4.0-1ubuntu1~18.0.4.1):
325 CantBeCopied(const CantBeCopied&) = delete;
326 CantBeCopied(CantBeCopied&&) = default;
329 std::optional<CantBeCopied> fooNOK() {
331 return result; // Legal C++, but does not compile with Ubuntu 18.04 default g++
333 std::optional<CantBeCopied> fooOK() {
335 return {std::move(result)}; // Compiles OK everywhere
338 The underlying bug is actually not specific to `std::optional` but this is the most common
339 case in f18 where the issue may occur. The actual bug can be reproduced with any class `B`
340 that has a perfect forwarding constructor taking `CantBeCopied` as argument:
341 `template<typename CantBeCopied> B(CantBeCopied&& x) x_{std::forward<CantBeCopied>(x)} {}`.
342 In such scenarios, Ubuntu 18.04 g++ fails to instantiate the move constructor
343 and to construct the returned value as it should, instead it complains about a
344 missing copy constructor.
346 Local result variables do not need to and should not be explicitly moved into optionals
347 if they have a copy constructor.