Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::format behaving different. between signed char / unsigned char

Tags:

c++

c++20

Is this behavior expected or as per standards (used VC compiler)?

Example 1 (signed char):

char s = 'R'
std::cout << s << std::endl;         // Prints R.
std::cout << std::format("{}\n", s); // Prints R.

Example 2 (unsigned char):

unsigned char u = 'R';
std::cout << u << std::endl;         // Prints R.
std::cout << std::format("{}\n", u); // Prints 82.

In the second example with std::format, u is printed as 82 instead of R, is it a bug or expected behavior?

Without using std::format, if just by std::cout, I get R in both examples.

like image 958
Pavan Chandaka Avatar asked Apr 19 '26 14:04

Pavan Chandaka


2 Answers

This is intentional and specified as such in the standard.

Both char and unsigned char are fundamentally numeric types. Normally only char has the additional meaning of representing a character. For example there are no unsigned char string literals. If unsigned char is used, often aliased to std::uint8_t, then it is normally supposed to represent a numeric value (or a raw byte of memory, although std::byte is a better choice for that).

So it makes sense to choose a numeric interpretation for unsigned char and a character interpretation for char by default. In both cases that can be overwritten with {:c} as specifier for a character interpretation and {:d} for a numeric interpretation.

I think operator<<'s behavior is the non-intuitive one, but that has been around for much longer and probably can't be changed.


Also note that signed char is a completely distinct type from both char and unsigned char and that it is implementation-defined whether char is an signed or unsigned integer type (but always distinct from both signed and unsigned char).

If you used signed char it would also be interpreted as numeric by default for the same reason as unsigned char is.

like image 136
user17732522 Avatar answered Apr 21 '26 08:04

user17732522


In the second example std::format, its printed as 82 instead of 'R', Is it an issue or standard?

This is behavior defined by the standard, according to [format.string.std]:

Type Meaning
... ...
c Copies the character static_­cast<charT>(value) to the output. Throws format_­error if value is not in the range of representable values for charT.
d to_­chars(first, last, value).
... ...
none The same as d. [Note 8: If the formatting argument type is charT or bool, the default is instead c or s, respectively. — end note]

For integer types, if type options are not specified, then d will be the default. Since unsigned char is an integer type, it will be interpreted as an integer, and its value will be the value converted by std::to_chars.

(Except for charT type and bool type, the default type options are c or s)

like image 30
康桓瑋 Avatar answered Apr 21 '26 08:04

康桓瑋



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!