Hi everyone,
In the past, libc++ has not been extremely good at conveying the experimental nature of some features to users or shipping TSes. For example, we shipped std::span
to users before we (the developers back then) considered it stable, which caused some problems down the road. Similary, some vendors have not been shipping the c++experimental.a
library (which contains the TSes that we implement). We didn’t have a good way for users to enable these experimental features while ensuring they wouldn’t start relying on (ABI or API) unstable features in production code, so it made little sense to ship them.
In addition to that, WG21 has recently been adding some large features like <ranges>
and <format>
to the Standard Library. These features are large and complex, and they take more than one release to implement and stabilize. However, they are often in a useful and interesting state even before we consider them fully stable, and we would like to have a way for users to try them out.
The goals of this proposal are:
- To make it possible for users to try experimental features in a simple and ergonomic way
- To make it difficult for users to accidentally start depending on unstable features in their code
The proposal
I’d like to propose adding a Clang flag (currently called -funstable
) which enables the following things:
- Not fully implemented language features. For example, before lambdas were working to a satisfactory level or before we had pinned down their ABI, we could have guarded that language feature behind
-funstable
. - Language TSes. For example, the Concepts TS could have been guarded behind such a flag before WG21 settled on the design we have now.
- Library TSes. For example, the Networking TS if we implemented it, or the
std::pmr
TS (which we do implement). - Not-yet-complete library features. For example,
<format>
mostly works, but it is technically not complete yet and we would rather not commit to an ABI at this point. Currently, we simply don’t ship that feature, with no way of enabling it. - Library features that we have implemented, but that we know are going to be broken by WG21 itself. For instance, WG21 made several API and ABI breaks to both
<ranges>
and<format>
. Implementers were aware of those upcoming breaks, so we couldn’t have shipped<ranges>
or<format>
even if they were ready at the time.
This flag is basically meant for folks who want to play around with new features to see how they work and give feedback, and also to provide some sort of guarantee to vendors that users can’t start relying on them by mistake.
Other names that were considered
-
-fexperimental
: We decided not to go with this because we wanted to convey the fact that said features were unstable, and hence dangerous to use in production code -
-std=c++latest
: This would be close to what MSVC does. We decided not to go down this route because we felt like it didn’t properly convey the notion of instability. Instead, we felt that-std=c++latest
could/should be a simple alias for whatever the latest known Standard is (which is not part of this patch).
One potential rebutal I can think of would be folks saying we should unconditionally ship these features even if they are not fully baked yet. Unfortunately, this does not meet goal (2). Concretely, doing that would mean that vendors who care strongly about stability will not ship these features out of fear (founded or not, although in my experience it is founded), and hence that would also defeat goal (1).
I also want to acknowledge that this creates a potential trap of hiding every feature behind that flag and hence simply delaying feature delivery to users. In my opinion, this is something that must be handled by exercising proper judgement. We always ship features when they are good enough not to be harmful, on a best effort basis. This shouldn’t change, and we shouldn’t wait for something to be “perfect” before shipping it.
I would like to have something like this in place for LLVM 15, which is branching at the end of July. The proposed design has been partially implemented in ⚙ D120160 [Clang] Add `-funstable` flag to enable unstable and experimental features and ⚙ D121141 [Clang] Add `-fexperimental-library` flag to enable unstable and experimental features: follow-up fixes, but I would like to have a discussion here to converge on a design before we ship it officially.
Does anyone have thoughts?
Thanks,
Louis