[libcxx-commits] [PATCH] D106763: [libc++][RFC] Disable incomplete library features.

Mark de Wever via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 25 05:57:31 PDT 2021


Mordante created this revision.
Mordante added reviewers: EricWF, Quuxplusone, cjdb, curdeius, ldionne, mclow.lists, zoecarver.
Mordante requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

At the moment the implementation of `std::format` is incomplete and
there will be ABI breaking changes in the future:

- Some shortcuts were taken to get a working basic version. Resolving these shortcuts will cause ABI breaking changes. For example the storage of the formatting arguments is currently done in a simple fashion leading to inefficient memory usage. Improving this is required by the Standard. However validating the required implementation is easier with the basics of `std::format` working. At that point there are proper tests to guard against regressions.
- The C++ committee accepts LWG issues that contain ABI breaks. For example http://wg21.link/P2216.

As long as a Standard isn't ratified libc++ makes no promises on ABI
stability for new features. After a Standard is ratified there's no good
way for libc++ to communicate to its users a feature isn't complete yet.
This is now the case with `std::format`, but the same may occur in the
future with other 'monolithic' features. For example, when Networking TS
will become part of the Standard.

This is a RFC to see how we can solve this problem. It aims to:

- Make it possible to develop high quality implementations in main, while not being afraid to make ABI breaking changes to improve the implementation.
- Make it possible to work on large features in main that can't be completed in one LLVM release cycle.
- Warn users when using not Standard conforming code.
- Warn users when using ABI unstable features.

Obviously using this escape hatch isn't ideal and when possible we
should attempt to avoid it.

In theory there's a simple solution. C++ has feature test macros that
allows users to query whether a feature is complete. However it's
uncertain whether users use this macro or just try to compile the code
and if it compiles they expect it to behave properly.

The current implementation in `<format>` uses `#error` this has the
advantage that including the header gives a nice diagnostic. For other
headers it might be better to only guard certain features. For example,
when the C++ committee's ABI break only affects a single function it's
possible to only disable this function. In that case there will be no
clear diagnostic how to enable the feature.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106763

Files:
  libcxx/docs/UsingLibcxx.rst
  libcxx/include/__config
  libcxx/include/format
  libcxx/test/std/utilities/format/format.error/format.error.pass.cpp


Index: libcxx/test/std/utilities/format/format.error/format.error.pass.cpp
===================================================================
--- libcxx/test/std/utilities/format/format.error/format.error.pass.cpp
+++ libcxx/test/std/utilities/format/format.error/format.error.pass.cpp
@@ -15,6 +15,9 @@
 
 // class format_error;
 
+// This define should be automatically defined by the test runner.
+// And there should be additional tests to see that the compilation fails when the proper defines aren't set.
+#define _LIBCPP_ENABLE_INCOMPLETE_FEATURES
 #include <format>
 #include <type_traits>
 #include <cstring>
Index: libcxx/include/format
===================================================================
--- libcxx/include/format
+++ libcxx/include/format
@@ -60,6 +60,10 @@
 #include <__format/format_parse_context.h>
 #include <version>
 
+#ifndef _LIBCPP_ENABLE_CXX20_INCOMPLETE_FORMAT
+#error The implementation of the format library is incomplete define _LIBCPP_ENABLE_CXX20_INCOMPLETE_FORMAT to use it.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -1362,6 +1362,10 @@
 #define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
 #endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES
 
+#if defined(_LIBCPP_ENABLE_INCOMPLETE_FEATURES)
+#define _LIBCPP_ENABLE_CXX20_INCOMPLETE_FORMAT
+#endif // _LIBCPP_ENABLE_INCOMPLETE_FEATURES
+
 #if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611
 #define _LIBCPP_HAS_NO_DEDUCTION_GUIDES
 #endif
Index: libcxx/docs/UsingLibcxx.rst
===================================================================
--- libcxx/docs/UsingLibcxx.rst
+++ libcxx/docs/UsingLibcxx.rst
@@ -196,6 +196,32 @@
   warning saying that `std::auto_ptr` is deprecated. If the macro is defined,
   no warning will be emitted. By default, this macro is not defined.
 
+**_LIBCPP_ENABLE_INCOMPLETE_FEATURES**:
+  Some library features in libc++ are marked as incomplete. Including
+  incomplete headers will result in a compilation failure, unless the
+  appropriate macro is defined. This is used for features that:
+
+    * Are large and partial implementations aren't easily detected during
+      compilation. For example:
+
+      * Calling a missing ranges algorithm leads to a compilation failure and
+        is easily detected.
+      * Calling an incomplete ``std::format`` function may compile, but at
+        run-time its behavior may not match the required behavior.
+
+    * Aren't guaranteed ABI stable yet, due to:
+
+      * The feature is still being developed.
+      * The C++ committee considers backporting ABI breaking changes to an
+        older version of the Standard. During the June 2021 plenary several ABI
+        breaking changes were retroactively applied to the C++20 Standard.
+
+  This macro is only used for features that are in a ratified version of the
+  C++ Standard. It's possible to determine the implementation status by testing
+  the appropriate feature test macro. Once a feature is complete it will be
+  available without defining a macro. By default, this macro is not defined.
+
+
 C++17 Specific Configuration Macros
 -----------------------------------
 **_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES**:
@@ -227,6 +253,13 @@
   ``[[nodiscard]]`` in dialects after C++17.  See :ref:`Extended Applications of [[nodiscard]] <nodiscard extension>`
   for more information.
 
+**_LIBCPP_ENABLE_CXX20_INCOMPLETE_FORMAT**:
+  This macros is used to enable the incomplete C++20 ``<format>`` header. This
+  macro automatically defined when defining
+  ``_LIBCPP_ENABLE_INCOMPLETE_FEATURES``. The implementation status of the
+  ``<format>`` header can be tested with the ``__cpp_lib_format`` feature
+  test macro.
+
 **_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES**:
   This macro is used to re-enable all the features removed in C++20. The effect
   is equivalent to manually defining each macro listed below.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106763.361495.patch
Type: text/x-patch
Size: 4080 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210725/01bf59a1/attachment.bin>


More information about the libcxx-commits mailing list