Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

@StephanTLavavej

Description

@StephanTLavavej

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:

  • The Sufficient Additional Overloads for <cmath> functions (and abs() 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), then std.compat should provide them in the global namespace.
  • nullptr_t. In P2465R3 Standard Library Modules std And std.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, so std.compat should provide ::nullptr_t.
  • lerp() and Special Math. These were added to std, but there are no C counterparts. I believe the case is strong to keep them out of the global namespace.
  • byte, its operators, and to_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++ adds std::hypot(x, y, z). According to the intended design, std.compat should provide only binary hypot (plus Sufficient Additional Overloads) in the global namespace; 3-arg hypot should be available in the std namespace only.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    LWG issue neededA wording defect that should be submitted to LWG as a new issuemodulesC++23 modules, C++20 header units

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions