[libcxx-commits] [libcxx] [libc++] Add coding guidelines to the docs (PR #117051)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 27 08:32:59 PST 2024


================
@@ -0,0 +1,172 @@
+.. _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 checks ``libcpp-robust-against-adl`` and ``libcpp-qualify-declval``.
+
+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, reducing compile times in turn.
+
+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 to not add ``_LIBCPP_HIDE_FROM_ABI`` is if a function is exported from the libc++ built library. In that case a
+function should be marked ``_LIBCPP_EXPORTED_FROM_ABI``. Virtual functions should be marked
+``_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``.
+
+Always define macros
+====================
+
+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
+
+instead of
+
+.. code-block:: cpp
+
+  #if SOMETHING
+  #  define _LIBCPP_SOMETHING_ENABLED
+  #endif
+
+This makes it significantly easier to catch missing includes, since Clang and GCC will warn when using and undefined
+marco inside an ``#if`` statement when using ``-Wundef``. Some macros in libc++ don't use this style yet, so this 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``. The form ``_LIBCPP_STD_VER >= <version>`` is preferred over ``_LIBCPP_STD_VER > <previous-version>``.
+
+This is mostly enforced by the clang-tidy check ``libcpp-cpp-version-check``.
+
+Use \_\_ugly\_\_ spellings of vendor attributes
----------------
ldionne wrote:

```suggestion
Use ``__ugly__`` spellings of vendor attributes
```

https://github.com/llvm/llvm-project/pull/117051


More information about the libcxx-commits mailing list