microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.11k stars 1.49k forks source link

`std.compat` wording is unclear about what's in the global namespace #3111

Open StephanTLavavej opened 2 years ago

StephanTLavavej commented 2 years ago

WG21-N4917 [std.modules]/3:

The named module std.compat exports the same declarations as the named module std, and additionally exports declarations in the global namespace corresponding to the declarations in namespace std that are provided by the C++ headers for C library facilities (Table 26).

When I wrote this wording, I thought I had cleverly expressed my intended design. Now that we're reviewing #3108, it appears that this wording is unclear and confusing.

The intended design: std.compat, as the name suggests, is a compatibility bridge for legacy codebases with extensive use of unqualified names from the C Standard Library. The <cmeow> headers definitely provide std::meow and may provide ::meow. The intention was for the std module to provide only std::meow, and for the std.compat module to provide both std::meow and ::meow (guaranteed, not "maybe"). However, this was never intended to provide declarations in the global namespace that would not have been provided by any Standard-conforming classic headers.

This is a clarity issue because of C++'s broken symmetries, where it has introduced things into the std namespace in the <cmeow> headers that aren't mirroring C's global declarations.

There are several specific examples, but the clearest example to showcase the design intent is <cstddef>'s std::byte. This was invented by C++, so with classic headers, neither <stddef.h> nor <cstddef> provide ::byte. Therefore, the std.compat module should not provide ::byte either - no legacy codebases could be relying on that.

The various interesting cases (this may not be an exhaustive list) are:

I am not exactly sure how to clarify the Standardese here, hence this tracking issue.

frederick-vs-ja commented 2 years ago

I think we should amend the requirements by cross referencing [support.c.headers.other], i.e., adding the following to the end of [std.modules]/3.

... , except the explicitly excluded declarations described in 17.15.7 [support.c.headers.other].

Via such change we can consistently specify whether ::meow is provided in <meow.h> and std.compat.

And the rest can be resolved by adding the following exceptions to [support.c.headers.other] (possibly processed together in LWG-3782).

... except for the functions described in 28.7.6 [sf.cmath], the 3-argument std::hypot function overloads (28.7.3 [c.math.hypot3]), the std::lerp function overloads (28.7.4 [c.math.lerp]), ...

StephanTLavavej commented 2 years ago

Thanks @frederick-vs-ja for filing LWG-3784 "std.compat should not provide ::byte and its friends"!

frederick-vs-ja commented 1 year ago

Now there's LWG-3799.

frederick-vs-ja commented 1 month ago

Recently I noticed that the currently wording clearly, at least to me, specifies that no ::atomic_meow provided by <stdatomic.h> is also provided by std.compat. In C++26 there'll possibly be similar new stuffs due to WG21-P3370.

Was such exclusion intentional? AFAIK <stdatomic.h> was never mentioned in WG21-P2465.