diff options
| author | Leitwolf11 | 2026-10-18 20:00:39 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-10-18 20:00:39 +0300 |
| commit | 8d1fb4807edc7920fbecd0554c9c61625827e19c (patch) | |
| tree | dd3d7e1d4f48ca27140a2bd5f970817ad02ae35a /Guide/PRINCIPLES.md | |
| download | progmasoft-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/PRINCIPLES.md')
| -rw-r--r-- | Guide/PRINCIPLES.md | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Guide/PRINCIPLES.md b/Guide/PRINCIPLES.md new file mode 100644 index 0000000..777de88 --- /dev/null +++ b/Guide/PRINCIPLES.md @@ -0,0 +1,59 @@ +<!-- SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> --> +<!-- SPDX-License-Identifier: CC-BY-4.0 --> + +# 1. Principles + +Every rule in this guide serves one of the principles below. When the guide says nothing about a case, decide by them, +in this order. + +## 1.1 Correct before fast, and both before clever + +Code that is wrong quickly is still wrong. Write the obvious correct version first, measure, and optimize where a +measurement says so. When an optimization makes code harder to read, the comment next to it says what it gains and how +that was measured. + +A clever construct that saves three lines but costs every later reader a minute is a bad trade. Prefer the form that +a reader new to the file understands on the first pass. + +## 1.2 The reader comes first + +Code is read far more often than it is written. Names say what a thing is for; types say who owns what; a function does +one thing that its name states. A reviewer should be able to judge a change from the diff and the code around it, +without reconstructing intent from history. + +## 1.3 Make invalid states unrepresentable + +Prefer types that cannot hold a wrong value over checks that reject one. An `enum class` instead of an `int` code, a +strong identifier type instead of a bare `std::uint32_t`, `std::optional<T>` instead of a sentinel, a factory that +validates instead of a constructor that cannot. Each check that a type makes unnecessary is a check nobody can forget. + +## 1.4 Failure is part of the interface + +A function that can fail says so in its signature: it returns `Expected<T>` or `Error`, and the caller must look at the +result. A precondition that a caller can violate is either checked and reported, or documented and asserted. Nothing +fails silently, and nothing fails by surprise. + +## 1.5 Determinism + +The same input gives the same output on every machine, every run. Output that depends on hash order, pointer values, +thread timing, the locale or the time of day is a defect unless it is the point of the program. Sort before you print; +iterate in an order you chose. + +## 1.6 Tools enforce what tools can + +Formatting, naming of members, include order and a long list of bug patterns are checked by `clang-format`, +`clang-tidy` and the compiler, with warnings as errors. A review then spends its attention on what tools cannot judge: +design, names, ownership, and whether the change does what it says. + +## 1.7 Consistency within a project beats consistency with the guide + +A project that adopts this guide over existing code converges gradually. A file follows the guide where it is touched; +a mechanical sweep is its own change, never mixed into a behavior change. Where a project deliberately deviates, it +writes the deviation down once (see [Adopting the guide](../ADOPTING.md)), and then the project's rule wins in that +project. + +## 1.8 Small, explicit dependencies + +Every dependency is a cost: build time, security surface, and a second set of conventions. Prefer the standard library, +then one well-chosen library per problem. A build target names the libraries it uses directly instead of relying on +what another target happens to bring in. |