microsoft / microsoft/STL

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

Open
#3,111 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

LWG issue needed modules
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

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 https://github.com/microsoft/STL/pull/3108#discussion_r973556555, @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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with WG21-N4917 [[std.modules]/3] and the discussion in #3108. Review the listed cases, including byte, nullptr_t, cmath overloads, lerp, and hypot, against the intended compatibility behavior. Done means producing unambiguous Standardese that specifies which declarations std.compat provides in the global namespace.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.