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