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

summaryrefslogtreecommitdiffhomepage
path: root/Guide/LANGUAGE.md
diff options
context:
space:
mode:
authorLeitwolf112026-10-31 13:01:04 +0300
committerLeitwolf112026-10-31 13:01:04 +0300
commit1f5458322669301f62599c1ec5dacb77b5dc2d8d (patch)
tree7e32402fa9c06014328a27d7972c2fb1a9484352 /Guide/LANGUAGE.md
parent8d1fb4807edc7920fbecd0554c9c61625827e19c (diff)
downloadprogmasoft-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.md44
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.