charconv.to.chars/integral.bool.fail.cpp is incorrect

Hi,

test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp claims that "Integral cannot be bool." and expects that calling to_chars() with a bool should fail to compile. This is an incorrect interpretation of the Standardese. MSVC's STL implements the overload set exactly as depicted in the Standard, so this test case compiles successfully.

The Standardese is N4820 20.19.2 [charconv.to.chars]/7 "Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value." Observe that these are depicted as overloads - not as a template.

If implemented as overloads, here's what happens:

C:\Temp>type woof.cpp
#include <stdio.h>

void ToChars(char) { puts("char"); }
void ToChars(signed char) { puts("signed char"); }
void ToChars(unsigned char) { puts("unsigned char"); }
void ToChars(short) { puts("short"); }
void ToChars(unsigned short) { puts("unsigned short"); }
void ToChars(int) { puts("int"); }
void ToChars(unsigned int) { puts("unsigned int"); }
void ToChars(long) { puts("long"); }
void ToChars(unsigned long) { puts("unsigned long"); }
void ToChars(long long) { puts("long long"); }
void ToChars(unsigned long long) { puts("unsigned long long"); }
void ToChars(float) { puts("float"); }
void ToChars(double) { puts("double"); }
void ToChars(long double) { puts("long double"); }

int main() {
    ToChars(false);
}

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 /permissive- woof.cpp && woof
woof.cpp
int

C:\Temp>clang-cl -m64 /EHsc /nologo /W4 /std:c++17 /permissive- -fno-ms-compatibility woof.cpp && woof
int

C1XX and Clang agree: the int overload is called. This is because bool undergoes a Promotion to int, and that's an exact match for int, while all other types require a Conversion from int to that type.

This test case should be reworked. I mention it, instead of simply fixing the test case, because it indicates that libcxx's implementation of to_chars() for integral types is also incorrect.

Thanks,
STL

Hi,

test/std/utilities/charconv/charconv.to.chars/integral.bool.fail.cpp claims that “Integral cannot be bool.” and expects that calling to_chars() with a bool should fail to compile. This is an incorrect interpretation of the Standardese. MSVC’s STL implements the overload set exactly as depicted in the Standard, so this test case compiles successfully.

The Standardese is N4820 20.19.2 [charconv.to.chars]/7 “Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value.” Observe that these are depicted as overloads - not as a template.

I suspect that that was not Jens’ intention when he wrote the wording.
cc’ing him.

– Marshall

Yes, that's unintended.

The facility is specified using overloads (not templates), because
it is anticipated that WG14 might want to use it at some point
in the future.

So, we have a bool -> int promotion that makes "to_chars(true)" call
"to_chars(1)", even though "bool" is none of the mentioned types.

Option 1: re-specify using a template (similar to rotl / rotr)

Option 2: add a deleted overload for "bool"

By the way, char16_t has the same problem, and likely
char32_t as well. Those were expressly discussed as
"not wanted" in LEWG, if I remember correctly.
I thought at that time that the ambiguous conversion
to int / unsigned int etc. will fix this, but
promotions are better than conversions, and there is
only one promotion.

I'm weakly in favor of adding the deleted overloads.

Jens