-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
The named module
std.compatexports the same declarations as the named modulestd, and additionally exports declarations in the global namespace corresponding to the declarations in namespacestdthat 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:
- The Sufficient Additional Overloads for
<cmath>functions (andabs()from<cstdlib>). If they can be defined in the global namespace (it appears that they can, although the Standardese is unclear as usual, and our implementation does so), thenstd.compatshould provide them in the global namespace. nullptr_t. In P2465R3 Standard Library ModulesstdAndstd.compat#3108 (comment), @frederick-vs-ja noted that while LWG-3484 has been filed (suggesting that<stddef.h>and<cstddef>should not declare::nullptr_t), C23 has accepted::nullptr_t(WG14-N3042, WG14-N3048). The "legacy" argument is weak, but overall it seems better to resolve this by having C23 supersede LWG-3484, sostd.compatshould provide::nullptr_t.lerp()and Special Math. These were added tostd, but there are no C counterparts. I believe the case is strong to keep them out of the global namespace.byte, its operators, andto_integer(). As mentioned, I believe these unquestionably need to be kept out of the global namespace.hypot(). This is the most unusual case (which I only realized during implementation), as C provides::hypot(x, y), C++ adds Sufficient Additional Overloads, and then C++ addsstd::hypot(x, y, z). According to the intended design,std.compatshould provide only binary hypot (plus Sufficient Additional Overloads) in the global namespace; 3-arghypotshould be available in thestdnamespace only.
I am not exactly sure how to clarify the Standardese here, hence this tracking issue.