2380. May <cstdlib> provide long ::abs(long) and long long ::abs(long long)?

Section: 20.5.1.2 [headers] Status: C++17 Submitter: Richard Smith Opened: 2014-03-31 Last modified: 2017-07-30

Priority: 2

View all other issues in [headers].

View all issues with C++17 status.

Discussion:

D.5 [depr.c.headers] p3 says:

[Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std. — end example]

This suggests that <cstdlib> may provide ::abs(long) and ::abs(long long). But this seems like it might contradict the normative wording of 20.5.1.2 [headers] p4:

Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

Note that this allows <cstdlib> to provide ::abs(int), but does not obviously allow ::abs(long) nor ::abs(long long), since they are not part of the header stdlib.h as specified in the C standard library.

29.9 [c.math] p7 adds signatures std::abs(long) and std::abs(long long), but not in a way that seems to allow ::abs(long) and ::abs(long long) to be provided.

I think the right approach here would be to allow <cstdlib> to either provide no ::abs declaration, or to provide all three declarations from namespace std, but it should not be permitted to provide only int abs(int). Suggestion:

Change in 20.5.1.2 [headers] p4:

[…]. It is unspecified whether these names (including any overloads added in Clauses 18 through 30 and Annex D) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

[2015-05, Lenexa]

MC: do we need to defer this?
PJP: just need to get my mind around it, already playing dirty games here, my reaction is just do it as it will help C++
STL: this is safe
TP: would be surprising if using abs didn't bring in all of the overloads
MC: that's Richard's argument
MC: move to ready

Proposed resolution:

This wording is relative to N3936.

  1. Modify 20.5.1.2 [headers] p4 as indicated:

    Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names (including any overloads added in Clauses 18 through 30 and Annex D) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).