Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / docs / DesignDocs / HeaderRemovalPolicy.rst
blob02cbc162318ef7683140a37ca4cf85f21884cc72
1 =====================
2 Header Removal Policy
3 =====================
5 Policy
6 ------
8 Libc++ is in the process of splitting larger headers into smaller modular
9 headers. This makes it possible to remove these large headers from other
10 headers. For example, instead of including ``<algorithm>`` entirely it is
11 possible to only include the headers for the algorithms used. When the
12 Standard indirectly adds additional header includes, using the smaller headers
13 aids reducing the growth of top-level headers. For example ``<atomic>`` uses
14 ``std::chrono::nanoseconds`` and included ``<chrono>``. In C++20 ``<chrono>``
15 requires ``<format>`` which adds several other headers (like ``<string>``,
16 ``<optional>``, ``<tuple>``) which are not needed in ``<atomic>``.
18 The benefit of using minimal headers is that the size of libc++'s top-level
19 headers becomes smaller. This improves the compilation time when users include
20 a top-level header. It also avoids header inclusion cycles and makes it easier
21 to port headers to platforms with reduced functionality.
23 A disadvantage is that users unknowingly depend on these transitive includes.
24 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).
29 To ease the removal of transitive includes in libc++, libc++ will remove
30 unnecessary transitive includes in newly supported C++ versions. This means
31 that users will have to fix their missing includes in order to upgrade to a
32 newer version of the Standard. Libc++ also reserves the right to remove
33 transitive includes at any other time, however new language versions will be
34 used as a convenient way to perform bulk removals of transitive includes.
36 For libc++ developers, this means that any transitive include removal must be
37 guarded by something of the form:
39 .. code-block:: cpp
41    #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
42    #  include <algorithm>
43    #  include <iterator>
44    #  include <utility>
45    #endif
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 Rationale
54 ---------
56 Removing headers is not only an issue for software developers, but also for
57 vendors. When a vendor updates libc++ several of their upstream packages might
58 fail to compile, forcing them to fix these packages or file a bug with their
59 upstream packages. Usually upgrading software to a new language standard is
60 done explicitly by software developers. This means they most likely will
61 discover and fix the missing includes, lessening the burden for the vendors.