blob: 493d07fb58c3b2fda052b20d58cbea71d1355e80 [file] [view]
# C++23 language changes
## Breaking changes
### Many transitive includes have been removed
In C++23, libc++ dropped a bunch of transitive includes, so a lot of includes
you were getting by accident now need to be explicitly included. Most popular
ones seem to be `<algorithm>`, `<memory>`, `<mutex>`, and `<vector>`.
Fix: Add missing includes. You can reference [cppreference.com](https://cppreference.com/)
for the includes of any function, type, or symbol.
### `std::unique_ptr`'s destructor became `constexpr`
In C++23, `std::unique_ptr`'s destructor became `constexpr`. As a result,
`std::unique_ptr<T>` has started to complain in more cases that `sizeof(T)`
is invalid when T is an incomplete type.
Fix: Ensure a type (`T`) is completely defined before it is used in unique_ptr,
typically by moving the definition of the type (`T`) before its use. In certain
cases, it might be hard to move the definition so you can move the destructor of
the class containing the `unique_ptr<T>` after the definition of type (`T`).
### `std::string` does not allow nullptr anymore
In C++23, `std::string` removed the constructor that accepted `nullptr`. You
can no longer assign `nullptr` to a `std::string` or return `nullptr` for a
fuction with return type of `std::string`. These actions now trigger a
compile-time error, preventing the runtime crashes that occurred in previous
versions.
Fix: Change your nullptr to "".
### `-Wfortify-source` with C++23 is more precise
Fortify performs safety checks at compile-time whenever possible, falling back to
runtime only when necessary. With C++23's increased use of `constexpr`, Fortify
can verify more conditions during compilation. This shifts some errors from
runtime to compile-time, potentially causing build failures in code now provably
known to be unsafe.
Fix: Look at the compile-time warnings and make the fix such that the size fits the
destination.
### Libc++ removed `__resize_default_init` for `resize_and_overwrite`
Libc++ removed [`__resize_default_init`](https://github.com/llvm/llvm-project/pull/157121)
recently because it was an internal API used only in a specific case. They decided to move
to the public one, `resize_and_overwrite`, that became available since C++23.
Fix: Replace all your uses of `__resize_default_init` with `resize_and_overwrite` for C++23.
## Non-Breaking changes
### Range-based For Loop issue was fixed
Since C++11, the range-based for loop had undefined behavior for specific cases because
they would result in dangling references. C++23 fixed this issue by extending the
lifetime of all temporaries in the range expression to the end of the loop. You can
find more information and examples in the design paper
[P2644R1](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2644r1.pdf).
## Other Changes
You can find the other new C++23 language features at
[https://en.cppreference.com/w/cpp/23.html](https://en.cppreference.com/w/cpp/23.html)