blob: c783a4f2e4e729b8f429949be8a260ec17bc83b2 [file] [log] [blame]
Nikolas Klauser59716472024-11-28 22:06:281.. _CodingGuidelines:
2
3========================
4libc++ Coding Guidelines
5========================
6
7.. contents::
8 :local:
9
10Use ``__ugly_names`` for implementation details
11===============================================
12
13Libc++ uses ``__ugly_names`` or ``_UglyNames`` for implementation details. These names are reserved for implementations,
14so users may not use them in their own applications. When using a name like ``T``, a user may have defined a macro that
15changes the meaning of ``T``. By using ``__ugly_names`` we avoid that problem.
16
17This is partially enforced by the clang-tidy check ``readability-identifier-naming`` and
18``libcxx/test/libcxx/system_reserved_names.gen.py``.
19
20Don't use argument-dependent lookup unless required by the standard
21===================================================================
22
23Unqualified function calls are susceptible to
24`argument-dependent lookup (ADL) <https://en.cppreference.com/w/cpp/language/adl>`_. This means calling
25``move(UserType)`` might not call ``std::move``. Therefore, function calls must use qualified names to avoid ADL. Some
26functions in the standard library `require ADL usage <http://eel.is/c++draft/contents#3>`_. Names of classes, variables,
27concepts, and type aliases are not subject to ADL. They don't need to be qualified.
28
29Function overloading also applies to operators. Using ``&user_object`` may call a user-defined ``operator&``. Use
30``std::addressof`` instead. Similarly, to avoid invoking a user-defined ``operator,``, make sure to cast the result to
31``void`` when using the ``,`` or avoid it in the first place. For example:
32
33.. code-block:: cpp
34
35 for (; __first1 != __last1; ++__first1, (void)++__first2) {
36 ...
37 }
38
Louis Dionne5e26fb12025-02-21 12:59:4639This is mostly enforced by the clang-tidy check ``libcpp-robust-against-adl``.
Nikolas Klauser59716472024-11-28 22:06:2840
41Avoid including public headers
42==============================
43
44libc++ uses implementation-detail headers for most code. These are in a directory that starts with two underscores
45(e.g. ``<__type_traits/decay.h>``). These detail headers are significantly smaller than their public counterparts.
46This reduces the amount of code that is included in a single public header, which reduces compile times.
47
48Add ``_LIBCPP_HIDE_FROM_ABI`` unless you know better
49====================================================
50
51``_LIBCPP_HIDE_FROM_ABI`` should be on every function in the library unless there is a reason not to do so. The main
52reason not to add ``_LIBCPP_HIDE_FROM_ABI`` is if a function is exported from the libc++ built library. In that case the
53function should be marked with ``_LIBCPP_EXPORTED_FROM_ABI``. Virtual functions should be marked with
54``_LIBCPP_HIDE_FROM_ABI_VIRTUAL`` instead.
55
56This is mostly enforced by the clang-tidy checks ``libcpp-hide-from-abi`` and ``libcpp-avoid-abi-tag-on-virtual``.
57
58Define configuration macros to 0 or 1
59=====================================
60
61Macros should usually be defined in all configurations, instead of defining them when they're enabled and leaving them
62undefined otherwise. For example, use
63
64.. code-block:: cpp
65
66 #if SOMETHING
67 # define _LIBCPP_SOMETHING_ENABLED 1
68 #else
69 # define _LIBCPP_SOMETHING_ENABLED 0
70 #endif
71
72and then check for ``#if _LIBCPP_SOMETHING_ENABLED`` instead of
73
74.. code-block:: cpp
75
76 #if SOMETHING
77 # define _LIBCPP_SOMETHING_ENABLED
78 #endif
79
80and then checking for ``#ifdef _LIBCPP_SOMETHING_ENABLED``.
81
82This makes it significantly easier to catch missing includes, since Clang and GCC will warn when using and undefined
83marco inside an ``#if`` statement when using ``-Wundef``. Some macros in libc++ don't use this style yet, so this only
84applies when introducing a new macro.
85
86This is partially enforced by the clang-tidy check ``libcpp-internal-ftms``.
87
88Use ``_LIBCPP_STD_VER``
89=======================
90
91libc++ defines the macro ``_LIBCPP_STD_VER`` for the different libc++ dialects. This should be used instead of
92``__cplusplus``.
93
94This is mostly enforced by the clang-tidy check ``libcpp-cpp-version-check``.
95
96Use ``__ugly__`` spellings of vendor attributes
97===============================================
98
99Vendor attributes should always be ``__uglified__`` to avoid naming clashes with user-defined macros. For gnu-style
100attributes this takes the form ``__attribute__((__foo__))``. C++11-style attributes look like ``[[_Clang::__foo__]]`` or
101``[[__gnu__::__foo__]]`` for Clang or GCC attributes respectively. Clang and GCC also support standard attributes in
102earlier language dialects than they were introduced. These should be spelled as ``[[__foo__]]``. MSVC currently doesn't
103provide alternative spellings for their attributes, so these should be avoided if at all possible.
104
105This is enforced by the clang-tidy check ``libcpp-uglify-attributes``.
106
107Use C++11 extensions in C++03 code if they simplify the code
108============================================================
109
110libc++ only supports Clang in C++98/03 mode. Clang provides many C++11 features in C++03, making it possible to write a
111lot of code in a simpler way than if we were restricted to C++03 features. Some use of extensions is even mandatory,
112since libc++ supports move semantics in C++03.
113
114Use ``using`` aliases instead of ``typedef``
115============================================
116
117``using`` aliases are generally easier to read and support templates. Some code in libc++ uses ``typedef`` for
118historical reasons.
119
120Write SFINAE with ``requires`` clauses in C++20-only code
121=========================================================
122
123``requires`` clauses can be significantly easier to read than ``enable_if`` and friends in some cases, since concepts
124subsume other concepts. This means that overloads based on traits can be written without negating more general cases.
125They also show intent better.
126
127Write ``enable_if`` as ``enable_if_t<conditon, int> = 0``
128=========================================================
129
130The form ``enable_if_t<condition, int> = 0`` is the only one that works in every language mode and for overload sets
131using the same template arguments otherwise. If the code must work in C++11 or C++03, the libc++-internal alias
132``__enable_if_t`` can be used instead.
133
134Prefer alias templates over class templates
135===========================================
136
137Alias templates are much more lightweight than class templates, since they don't require new instantiations for
138different types. If the only member of a class is an alias, like in type traits, alias templates should be used if
139possible. They do force more eager evaluation though, which can be a problem in some cases.
140
141Apply ``[[nodiscard]]`` where relevant
142======================================
143
144Libc++ adds ``[[nodiscard]]`` whenever relevant to catch potential bugs. The standards committee has decided to _not_
145have a recommended practice where to put them, so libc++ applies it whenever it makes sense to catch potential bugs.
146
147``[[nodiscard]]`` should be applied to functions
148
149- where discarding the return value is most likely a correctness issue. For example a locking constructor in
150 ``unique_lock``.
151
152- where discarding the return value likely points to the user wanting to do something different. For example
153 ``vector::empty()``, which probably should have been ``vector::clear()``.
154
155 This can help spotting bugs easily which otherwise may take a very long time to find.
156
157- which return a constant. For example ``numeric_limits::min()``.
158- which only observe a value. For example ``string::size()``.
159
160 Code that discards values from these kinds of functions is dead code. It can either be removed, or the programmer
161 meant to do something different.
162
163- where discarding the value is most likely a misuse of the function. For example ``std::find(first, last, val)``.
164
165 This protects programmers from assuming too much about how the internals of a function work, making code more robust
166 in the presence of future optimizations.
167
168Applications of ``[[nodiscard]]`` are code like any other code, so we aim to test them on public interfaces. This can be
169done with a ``.verify.cpp`` test. Many examples are available. Just look for tests with the suffix
170``.nodiscard.verify.cpp``.
Louis Dionne01512d22024-12-10 15:15:13171
172Don't use public API names for symbols on the ABI boundary
173==========================================================
174
175Most functions in libc++ are defined in headers either as templates or as ``inline`` functions. However, we sometimes
176need or want to define functions in the built library. Symbols that are declared in the headers and defined in the
177built library become part of the ABI of libc++, which must be preserved for backwards compatibility. This means that
178we can't easily remove or rename such symbols except in special cases.
179
180When adding a symbol to the built library, make sure not to use a public name directly. Instead, define a
181``_LIBCPP_HIDE_FROM_ABI`` function in the headers with the public name and have it call a private function in the built
182library. This approach makes it easier to make changes to libc++ like move something from the built library to the
183headers (which is sometimes required for ``constexpr`` support).
184
185When defining a function at the ABI boundary, it can also be useful to consider which attributes (like ``[[gnu::pure]]``
186and ``[[clang::noescape]]``) can be added to the function to improve the compiler's ability to optimize.
Nikolas Klauser48b2ce92025-01-21 21:28:13187
188Library-internal type aliases should be annotated with ``_LIBCPP_NODEBUG``
189==========================================================================
190
191Libc++ has lots of internal type aliases. Accumulated, these can result in significant amounts of debug information that
192users generally don't care about, since users don't try to debug standard library facilities in most cases. For that
193reason, all library-internal type aliases that aren't function-local should be annotated with ``_LIBCPP_NODEBUG`` to
Nikolas Klauserfb44f002025-03-23 20:01:25194prevent compilers from generating said debug information. Aliases inside type traits (i.e. aliases named ``type``)
195should be annotated for the same reason.
Nikolas Klauser48b2ce92025-01-21 21:28:13196
197This is enforced by the clang-tidy check ``libcpp-nodebug-on-aliases``.