diff options
| author | Leitwolf11 | 2026-10-31 13:01:04 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-10-31 13:01:04 +0300 |
| commit | 1f5458322669301f62599c1ec5dacb77b5dc2d8d (patch) | |
| tree | 7e32402fa9c06014328a27d7972c2fb1a9484352 /Guide/LANGUAGE.md | |
| parent | 8d1fb4807edc7920fbecd0554c9c61625827e19c (diff) | |
| download | progmasoft-cpp-docs/cpp17-and-cpp20.tar.gz | |
Cover C++17 as well as C++20docs/cpp17-and-cpp20
A project now picks one version. C++20 stays the default, and C++17 is
for libraries meant for other people's projects, because it is still the
widest common target and works in every later standard.
Section 5.13 gives the C++17 form of each C++20 feature the guide uses
and the checks such a project needs: CI in the versions it promises, with
each compiler, and headers that compile in default compiler modes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'Guide/LANGUAGE.md')
| -rw-r--r-- | Guide/LANGUAGE.md | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/Guide/LANGUAGE.md b/Guide/LANGUAGE.md index 7163472..7858103 100644 --- a/Guide/LANGUAGE.md +++ b/Guide/LANGUAGE.md @@ -3,8 +3,16 @@ # 5. Language -The guide targets C++20 exactly: `-std=c++20`, no compiler extensions (`-Wpedantic` is on). A C++23 feature is used only -through a library that provides it for C++20, such as `llvm::Expected` in place of `std::expected`. +The guide covers two language versions, and a project picks one: + +- **C++20** is the default, for applications and for libraries used inside one product. +- **C++17** is for a library meant for other people's projects, because C++17 is still the widest common target and code + written for it also works in every later standard. A C++20 library would leave those users out. + +A project builds with exactly its version, `-std=c++20` or `-std=c++17`, and no compiler extensions (`-Wpedantic` is on). +Its deviations do not change the version: a C++17 project uses no C++20 feature, even where a compiler accepts one. +A feature of a later standard is used only through a library that provides it, such as `llvm::Expected` in place of +`std::expected`. [Section 5.13](#513-c17-projects) gives the C++17 form of what the other sections write in C++20. ## 5.1 Functions @@ -168,3 +176,35 @@ validates it. | Non-`const` global and static variables | state passed explicitly, owned by an object with a clear lifetime | | `alloca`, `setjmp`/`longjmp` | ordinary allocation and returns | | User-defined literals | named functions or constructors, except the standard ones such as `std::chrono` suffixes | + +## 5.13 C++17 projects + +The rest of this guide applies unchanged. Where a section uses a C++20 feature, a C++17 project writes this instead: + +| C++20 | C++17 | +| --- | --- | +| Concepts and `requires` | a named trait, `kIsInteger<Type>`, used by `std::enable_if_t` in a defaulted template parameter; `static_assert` when no overload depends on it | +| `operator==` and `operator<=>` `= default` | written out over `std::tie` of all fields, with a test that fails when a field is left out | +| Designated initializers | default construct, then assign the fields; a factory function when this repeats | +| `std::span` | `const std::vector<T> &`, or a view such as `llvm::ArrayRef` where the project has one | +| `std::ranges` | the iterator algorithms: `std::sort(items.begin(), items.end())` | +| `std::bit_cast` | `static_cast` between integers, `std::memcpy` into a value otherwise | +| `consteval`, `constinit` | `constexpr` | +| Template lambdas | a function template in a `Detail` namespace | +| `std::erase_if` | erase-remove: `items.erase(std::remove_if(...), items.end())` | +| `contains`, `starts_with`, `ends_with` | `find`, `compare` or `substr` | +| `std::remove_cvref_t`, `std::identity` | one small header of the project, with a comment naming what it stands for | +| `std::format` | `fmt`, or streaming | +| `std::jthread` | `std::thread`, joined explicitly | +| `using enum` | qualified enumerators | +| `[[likely]]`, `[[unlikely]]` | nothing | + +Code written for C++17 is promised to later standards too, so its checks have to reach them: + +- **CI builds and tests in C++17 and in the newest standard the project supports.** A rule of C++20 can reject C++17 code, + such as the rewritten comparison operators. +- **CI builds with each compiler the project supports, not only Clang.** Clang accepts designated initializers in C++17 + and warns; MSVC rejects them. Clang's `-Wc++20-extensions` shows most of these before CI does. +- **Headers compile under the default modes of the compilers.** MSVC is permissive in C++17 unless `/permissive-` is + given, and a user of the library may not give it. A non-capturing lambda that reads a local `constexpr`, for instance, + is an error there. |