|  | .. _CodingGuidelines: | 
|  |  | 
|  | ======================== | 
|  | libc++ Coding Guidelines | 
|  | ======================== | 
|  |  | 
|  | .. contents:: | 
|  | :local: | 
|  |  | 
|  | Use ``__ugly_names`` for implementation details | 
|  | =============================================== | 
|  |  | 
|  | Libc++ uses ``__ugly_names`` or ``_UglyNames`` for implementation details. These names are reserved for implementations, | 
|  | so users may not use them in their own applications. When using a name like ``T``, a user may have defined a macro that | 
|  | changes the meaning of ``T``. By using ``__ugly_names`` we avoid that problem. | 
|  |  | 
|  | This is partially enforced by the clang-tidy check ``readability-identifier-naming`` and | 
|  | ``libcxx/test/libcxx/system_reserved_names.gen.py``. | 
|  |  | 
|  | Don't use argument-dependent lookup unless required by the standard | 
|  | =================================================================== | 
|  |  | 
|  | Unqualified function calls are susceptible to | 
|  | `argument-dependent lookup (ADL) <https://en.cppreference.com/w/cpp/language/adl>`_. This means calling | 
|  | ``move(UserType)`` might not call ``std::move``. Therefore, function calls must use qualified names to avoid ADL. Some | 
|  | functions in the standard library `require ADL usage <http://eel.is/c++draft/contents#3>`_. Names of classes, variables, | 
|  | concepts, and type aliases are not subject to ADL. They don't need to be qualified. | 
|  |  | 
|  | Function overloading also applies to operators. Using ``&user_object`` may call a user-defined ``operator&``. Use | 
|  | ``std::addressof`` instead. Similarly, to avoid invoking a user-defined ``operator,``, make sure to cast the result to | 
|  | ``void`` when using the ``,`` or avoid it in the first place. For example: | 
|  |  | 
|  | .. code-block:: cpp | 
|  |  | 
|  | for (; __first1 != __last1; ++__first1, (void)++__first2) { | 
|  | ... | 
|  | } | 
|  |  | 
|  | This is mostly enforced by the clang-tidy check ``libcpp-robust-against-adl``. | 
|  |  | 
|  | Avoid including public headers | 
|  | ============================== | 
|  |  | 
|  | libc++ uses implementation-detail headers for most code. These are in a directory that starts with two underscores | 
|  | (e.g. ``<__type_traits/decay.h>``). These detail headers are significantly smaller than their public counterparts. | 
|  | This reduces the amount of code that is included in a single public header, which reduces compile times. | 
|  |  | 
|  | Add ``_LIBCPP_HIDE_FROM_ABI`` unless you know better | 
|  | ==================================================== | 
|  |  | 
|  | ``_LIBCPP_HIDE_FROM_ABI`` should be on every function in the library unless there is a reason not to do so. The main | 
|  | reason not to add ``_LIBCPP_HIDE_FROM_ABI`` is if a function is exported from the libc++ built library. In that case the | 
|  | function should be marked with ``_LIBCPP_EXPORTED_FROM_ABI``. Virtual functions should be marked with | 
|  | ``_LIBCPP_HIDE_FROM_ABI_VIRTUAL`` instead. | 
|  |  | 
|  | This is mostly enforced by the clang-tidy checks ``libcpp-hide-from-abi`` and ``libcpp-avoid-abi-tag-on-virtual``. | 
|  |  | 
|  | Define configuration macros to 0 or 1 | 
|  | ===================================== | 
|  |  | 
|  | Macros should usually be defined in all configurations, instead of defining them when they're enabled and leaving them | 
|  | undefined otherwise. For example, use | 
|  |  | 
|  | .. code-block:: cpp | 
|  |  | 
|  | #if SOMETHING | 
|  | #  define _LIBCPP_SOMETHING_ENABLED 1 | 
|  | #else | 
|  | #  define _LIBCPP_SOMETHING_ENABLED 0 | 
|  | #endif | 
|  |  | 
|  | and then check for ``#if _LIBCPP_SOMETHING_ENABLED`` instead of | 
|  |  | 
|  | .. code-block:: cpp | 
|  |  | 
|  | #if SOMETHING | 
|  | #  define _LIBCPP_SOMETHING_ENABLED | 
|  | #endif | 
|  |  | 
|  | and then checking for ``#ifdef _LIBCPP_SOMETHING_ENABLED``. | 
|  |  | 
|  | This makes it significantly easier to catch missing includes: Clang and GCC with ``-Wundef`` enabled will warn | 
|  | when using an undefined macro inside an ``#if`` statement. Some macros in libc++ don't use this style yet, | 
|  | so this guideline only applies when introducing a new macro. | 
|  |  | 
|  | This is partially enforced by the clang-tidy check ``libcpp-internal-ftms``. | 
|  |  | 
|  | Use ``_LIBCPP_STD_VER`` | 
|  | ======================= | 
|  |  | 
|  | libc++ defines the macro ``_LIBCPP_STD_VER`` for the different libc++ dialects. This should be used instead of | 
|  | ``__cplusplus``. | 
|  |  | 
|  | This is mostly enforced by the clang-tidy check ``libcpp-cpp-version-check``. | 
|  |  | 
|  | Use ``__ugly__`` spellings of vendor attributes | 
|  | =============================================== | 
|  |  | 
|  | Vendor attributes should always be ``__uglified__`` to avoid naming clashes with user-defined macros. For gnu-style | 
|  | attributes this takes the form ``__attribute__((__foo__))``. C++11-style attributes look like ``[[_Clang::__foo__]]`` or | 
|  | ``[[__gnu__::__foo__]]`` for Clang or GCC attributes respectively. Clang and GCC also support standard attributes in | 
|  | earlier language dialects than they were introduced. These should be spelled as ``[[__foo__]]``. MSVC currently doesn't | 
|  | provide alternative spellings for their attributes, so these should be avoided if at all possible. | 
|  |  | 
|  | This is enforced by the clang-tidy check ``libcpp-uglify-attributes``. | 
|  |  | 
|  | Use C++11 extensions in C++03 code if they simplify the code | 
|  | ============================================================ | 
|  |  | 
|  | libc++ supports the C++98/03 mode only with the Clang compiler. Clang provides many C++11 features | 
|  | in C++03, making it possible to write a lot of code in a simpler way than if we were restricted to C++03 features. | 
|  | Some use of extensions is even mandatory, since libc++ supports move semantics in C++03. | 
|  |  | 
|  | Use ``using`` aliases instead of ``typedef`` | 
|  | ============================================ | 
|  |  | 
|  | ``using`` aliases are generally easier to read and support templates. Some code in libc++ uses ``typedef`` for | 
|  | historical reasons. | 
|  |  | 
|  | Write SFINAE with ``requires`` clauses in C++20-only code | 
|  | ========================================================= | 
|  |  | 
|  | ``requires`` clauses can be significantly easier to read than ``enable_if`` and friends in some cases, since concepts | 
|  | subsume other concepts. This means that overloads based on traits can be written without negating more general cases. | 
|  | They also show intent better. | 
|  |  | 
|  | Write ``enable_if`` as ``enable_if_t<condition, int> = 0`` | 
|  | ========================================================== | 
|  |  | 
|  | The form ``enable_if_t<condition, int> = 0`` is the only one that works in every language mode and for overload sets | 
|  | using the same template arguments otherwise. If the code must work in C++11 or C++03, the libc++-internal alias | 
|  | ``__enable_if_t`` can be used instead. | 
|  |  | 
|  | Prefer alias templates over class templates | 
|  | =========================================== | 
|  |  | 
|  | Alias templates are much more lightweight than class templates, since they don't require new instantiations for | 
|  | different types. If the only member of a class is an alias, like in type traits, alias templates should be used if | 
|  | possible. They do force more eager evaluation though, which can be a problem in some cases. | 
|  |  | 
|  | Apply ``[[nodiscard]]`` where relevant | 
|  | ====================================== | 
|  |  | 
|  | Libc++ adds ``[[nodiscard]]`` whenever relevant to catch potential bugs. The standards committee has decided to _not_ | 
|  | have a recommended practice where to put them, so libc++ applies it whenever it makes sense to catch potential bugs. | 
|  |  | 
|  | ``[[nodiscard]]`` should be applied to functions | 
|  |  | 
|  | - where discarding the return value is most likely a correctness issue. For example a locking constructor in | 
|  | ``unique_lock``. | 
|  |  | 
|  | - where discarding the return value likely points to the user wanting to do something different. For example | 
|  | ``vector::empty()``, which probably should have been ``vector::clear()``. | 
|  |  | 
|  | This can help spotting bugs easily which otherwise may take a very long time to find. | 
|  |  | 
|  | - which return a constant. For example ``numeric_limits::min()``. | 
|  | - which only observe a value. For example ``string::size()``. | 
|  |  | 
|  | Code that discards values from these kinds of functions is dead code. It can either be removed, or the programmer | 
|  | meant to do something different. | 
|  |  | 
|  | - where discarding the value is most likely a misuse of the function. For example ``std::find(first, last, val)``. | 
|  |  | 
|  | This protects programmers from assuming too much about how the internals of a function work, making code more robust | 
|  | in the presence of future optimizations. | 
|  |  | 
|  | Applications of ``[[nodiscard]]`` are code like any other code, so we aim to test them on public interfaces. This can be | 
|  | done with a ``.verify.cpp`` test. Many examples are available. Just look for tests with the suffix | 
|  | ``.nodiscard.verify.cpp``. | 
|  |  | 
|  | Don't use public API names for symbols on the ABI boundary | 
|  | ========================================================== | 
|  |  | 
|  | Most functions in libc++ are defined in headers either as templates or as ``inline`` functions. However, we sometimes | 
|  | need or want to define functions in the built library. Symbols that are declared in the headers and defined in the | 
|  | built library become part of the ABI of libc++, which must be preserved for backwards compatibility. This means that | 
|  | we can't easily remove or rename such symbols except in special cases. | 
|  |  | 
|  | When adding a symbol to the built library, make sure not to use a public name directly. Instead, define a | 
|  | ``_LIBCPP_HIDE_FROM_ABI`` function in the headers with the public name and have it call a private function in the built | 
|  | library. This approach makes it easier to make changes to libc++ like move something from the built library to the | 
|  | headers (which is sometimes required for ``constexpr`` support). | 
|  |  | 
|  | When defining a function at the ABI boundary, it can also be useful to consider which attributes (like ``[[gnu::pure]]`` | 
|  | and ``[[clang::noescape]]``) can be added to the function to improve the compiler's ability to optimize. | 
|  |  | 
|  | Library-internal type aliases should be annotated with ``_LIBCPP_NODEBUG`` | 
|  | ========================================================================== | 
|  |  | 
|  | Libc++ has lots of internal type aliases. Accumulated, these can result in significant amounts of debug information that | 
|  | users generally don't care about, since users don't try to debug standard library facilities in most cases. For that | 
|  | reason, all library-internal type aliases that aren't function-local should be annotated with ``_LIBCPP_NODEBUG`` to | 
|  | prevent compilers from generating said debug information. Aliases inside type traits (i.e. aliases named ``type``) | 
|  | should be annotated for the same reason. | 
|  |  | 
|  | This is enforced by the clang-tidy check ``libcpp-nodebug-on-aliases``. |