Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/Guide/COMMENTS-AND-DOCUMENTATION.md
diff options
context:
space:
mode:
authorLeitwolf112026-10-18 20:00:39 +0300
committerLeitwolf112026-10-18 20:00:39 +0300
commit8d1fb4807edc7920fbecd0554c9c61625827e19c (patch)
treedd3d7e1d4f48ca27140a2bd5f970817ad02ae35a /Guide/COMMENTS-AND-DOCUMENTATION.md
downloadprogmasoft-cpp-8d1fb4807edc7920fbecd0554c9c61625827e19c.tar.gz
Write the first revision of Progmasoft C++ Style
Progmasoft C++ Style is a style guide for C++20, written for anyone who wants a complete rule set to adopt. It writes down the conventions the Progmasoft C++ projects already follow (naming, the clang-format and clang-tidy profiles, exception-free error handling, Doxygen) and decides what they left open. Thirteen chapters under Guide/: 1. Principles: what the guide optimizes for and how to decide a case it does not cover. 2. Formatting: the full .clang-format profile, the reason for each choice, and the rules the tool cannot apply. 3. Naming: casing for every kind of name, acronyms, choosing words, namespaces, files. 4. Files and headers: extensions, #pragma once, includes, what goes in a header, the order inside a class, file size, vendored code. 5. Language: functions, auto, initialization, const and constexpr, casts, integers, strings, enumerations, templates and concepts, lambdas, control flow, and the features not used. 6. Types and classes: struct or class, final, construction, the rule of zero, inheritance, operators, strong types, optional and variant. 7. Errors: no exceptions by default, Expected and Error, invariants, fatal defects, destructors, diagnostics. 8. Ownership and memory: owners and borrowers, views and lifetimes, RAII, containers and deterministic iteration, allocation, undefined behavior. 9. Comments and documentation: Doxygen for public declarations, comments that explain why, TODOs that name an issue. 10. C interfaces: C11 headers, prefixes, opaque types, ownership and failure across the boundary, stability. 11. Concurrency: sharing less, threads, locks, thread-safety annotations, atomics, statics. 12. Testing: unit tests, fuzzing, sanitizers, benchmarks, coverage. 13. Tooling: the compiler flags, the full .clang-tidy profile with the reason for every disabled check, other checks, version pinning. The guide prescribes no test, fuzzing or benchmark framework and no error library; it prescribes how they are used. ADOPTING.md explains how a project points to the guide, copies the profiles and records its deviations. CONTRIBUTING.md explains how to propose a change. The text is licensed under CC BY 4.0. The configuration and code examples are dedicated to the public domain under CC0 1.0, so projects can copy them under their own license. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'Guide/COMMENTS-AND-DOCUMENTATION.md')
-rw-r--r--Guide/COMMENTS-AND-DOCUMENTATION.md82
1 files changed, 82 insertions, 0 deletions
diff --git a/Guide/COMMENTS-AND-DOCUMENTATION.md b/Guide/COMMENTS-AND-DOCUMENTATION.md
new file mode 100644
index 0000000..7cdffb7
--- /dev/null
+++ b/Guide/COMMENTS-AND-DOCUMENTATION.md
@@ -0,0 +1,82 @@
+<!-- SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> -->
+<!-- SPDX-License-Identifier: CC-BY-4.0 -->
+
+# 9. Comments and documentation
+
+Comments are written in US English, in full sentences that end with a period. They explain what the code cannot say for
+itself: what an interface promises, why a choice was made, and what would break if someone changed it.
+
+## 9.1 Documentation comments
+
+Every public declaration in a header, meaning every type, function, enumerator, constant and data member that another
+component can use, has a Doxygen comment written with `///`:
+
+```cpp
+/// Derive the blocks that are live on entry to each block of a function.
+/// The result lists blocks in ascending id order, so it is stable across
+/// runs and can be compared in tests.
+/// @param graph Control-flow graph of the function; must be verified.
+/// @param uses Variables read by each block.
+/// @return Live-in sets, or an error when the graph and the use table
+/// describe different numbers of blocks.
+[[nodiscard]] auto
+AnalyzeLiveness(const ControlFlowGraph &graph, const UseTable &uses)
+ -> llvm::Expected<LivenessResult>;
+```
+
+- **The first sentence says what the declaration is or does**, as a summary that stands on its own in a list of
+ declarations. Start a function's summary with a verb in the imperative: "Derive", "Return", "Create". Start a type's
+ summary with a noun phrase.
+- **Then the contract**: preconditions, what the result guarantees (order, ownership, lifetime of returned views), what
+ happens on failure, and whether the function is thread-safe when that is not obvious.
+- **`@param`** for every parameter whose meaning or constraints the name does not fully convey, and **`@return`** for
+ every non-void function. `@pre`, `@post` and `@note` may be used where they help.
+- **Do not document the implementation** in a header. A comment that says "uses a hash map internally" is wrong the day
+ the implementation changes, and the caller should not depend on it.
+- **A longer description** may use a `/** ... */` block with `@brief`, lists and examples, as Doxygen renders them.
+- **Doxygen runs in CI** with warnings as errors for the public headers, so an undocumented or misdocumented declaration
+ fails the build.
+
+## 9.2 Implementation comments
+
+Inside a function, comment **why**, not what:
+
+```cpp
+// The verifier already rejected unreachable blocks, so every block here has a
+// predecessor and the entry block is the only root of the dominator tree.
+```
+
+```cpp
+// Avoid: restates the code.
+// Increment the counter.
+++counter;
+```
+
+Comment especially:
+
+- an invariant the code relies on and a later change could break: identity, ordering, ownership, a protocol bound;
+- a workaround for a compiler, library or platform defect, with a link to the report and the condition for removing it;
+- a choice that looks wrong but is deliberate, and why the obvious alternative does not work;
+- the reason for every magic number that cannot be a named constant.
+
+Keep a comment next to the code it explains, and change it in the same commit as the code.
+
+## 9.3 TODOs
+
+A `TODO` names the issue that tracks it: `// TODO(#123): accept signed offsets once the wire format has them.` A TODO
+without an issue is either done now or not written. Do not leave commented-out code; version control keeps the history.
+
+## 9.4 File comments
+
+A file starts with its license header and has no other boilerplate: no author list, no creation date, no change log.
+When a file needs an overview, such as a component's main header, write it as the documentation comment of the
+namespace or of the main type.
+
+## 9.5 Words
+
+- Say what a thing is for, in the vocabulary of its users, not of its implementation.
+- Prefer the active voice and the present tense: "The parser stops at the first error", not "The parsing will be
+ stopped".
+- Use the project's terms consistently. If the project calls something a "block", do not call it a "node" in one comment
+ and a "basic block" in another.
+- Do not use comments for jokes, blame or emotions. A comment is read years later, out of context, by someone in a hurry.