Skip to content

Commit 1213d4e

Browse files
authored
[libc++] Stabilize transitive includes for C++23 (#134143)
Our mechanism to retain transitive includes for backwards compatibility was previously not taking into account C++23: this means that users on C++23 would not get any protection against the removal of transitive includes. This was fine when C++23 was still not used widely and it allowed us to make build time improvements for such "bleeding edge" users. It also didn't take into account the larger topic of providing a backwards compatible set of declarations, which is the real goal of this mechanism. However, now that C++23 is used pretty widely, we should start providing transitive includes backwards compatibility for users of that language mode too. This patch documents that requirement and mentions backwards compatibility of the set of declarations as well, meaning we may also add internal headers in the `_LIBCPP_REMOVE_TRANSITIVE_INCLUDES` blocks going forward. There are no actual changes to the code since we haven't removed transitive includes since the last release. However, starting now, we should guard any removal of transitive includes behind #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23 instead of #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1 parent 810f06e commit 1213d4e

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

libcxx/docs/DesignDocs/HeaderRemovalPolicy.rst

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ to port headers to platforms with reduced functionality.
2222

2323
A disadvantage is that users unknowingly depend on these transitive includes.
2424
Thus removing an include might break their build after upgrading a newer
25-
version of libc++. For example, ``<algorithm>`` is often forgotten but using
26-
algorithms will still work through those transitive includes. This problem is
27-
solved by modules, however in practice most people do not use modules (yet).
25+
version of libc++ by reducing the set of declarations provided by a header.
26+
For example, ``<algorithm>`` is often forgotten but using algorithms will
27+
still work through those transitive includes. This problem is solved by modules,
28+
however in practice most people do not use modules (yet).
2829

2930
To ease the removal of transitive includes in libc++, libc++ will remove
3031
unnecessary transitive includes in newly supported C++ versions. This means
@@ -33,21 +34,34 @@ newer version of the Standard. Libc++ also reserves the right to remove
3334
transitive includes at any other time, however new language versions will be
3435
used as a convenient way to perform bulk removals of transitive includes.
3536

36-
For libc++ developers, this means that any transitive include removal must be
37-
guarded by something of the form:
37+
However, libc++ intends not to gratuitously break users on stable versions of
38+
the Standard. Hence, we intend to maintain backwards compatibility of the
39+
declarations we provide in a header, within reason. We reserve the right to
40+
break such backwards compatibility in the future, however we will strive to
41+
do it in a user-friendly way, again within reason. For libc++ developers, this
42+
means that any transitive include removal of a public header must be guarded by
43+
something of the form:
3844

3945
.. code-block:: cpp
4046
41-
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
47+
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
4248
# include <algorithm>
4349
# include <iterator>
4450
# include <utility>
4551
#endif
4652
47-
When users define ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES``, libc++ will not
48-
include transitive headers, regardless of the language version. This can be
49-
useful for users to aid the transition to a newer language version, or by users
50-
who simply want to make sure they include what they use in their code.
53+
Occasionally, private headers may also be included transitively for backwards
54+
compatibility in the same manner. We currently strive to provide backwards
55+
compatibility on the set of declarations provided by a header in all Standard
56+
modes starting with **C++23**. Note that this is very difficult to actually
57+
enforce, so this is done only on a best effort basis.
58+
59+
When users define ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES``, libc++ will not include
60+
transitive headers, regardless of the language version. This can be useful for users
61+
to aid the transition to a newer language version, or by users who simply want to
62+
make sure they include what they use in their code. However, note that defining this
63+
macro means that the set of declarations and transitive includes provided by the library
64+
may change from release to release, which can break your code.
5165

5266

5367
Rationale

0 commit comments

Comments
 (0)