Date: Wed, 8 Jul 2026 15:09:50 +0000
> That's not correct. Since C++11, char is required to support all UTF-8 code units (that means the minimum size for a byte is 8 bits). The addition of char8_t has not changed the requirement on char.
> Therefore, it can't be UB.
> Whether the code unit stored in the char makes sense when interpreted under the narrow character set, it's a completely different story.
First of, isn't the "whether the code unit stored in the char makes sense" the whole point?
Second "that it can fit" doesn't mean "that's how it is interpreted".
How do you explain EBCDIC systems?
There was never a promise that every Unicode character would be translated as utf-8 for char. It can't, otherwise EBCDIC wouldn't work.
`char` lives in a limbo state, when it compiles and runs it must definitely have an encoding, but exactly what that encoding is is not defined anywhere, and worse it can actually be many things at once and nobody knows exactly.
We tend to forget that utf-8 is a hack, it's a hack that was meant to run on systems that work as a superset of ASCII. And it works, so much so that people think the systems they are running on are utf-8, when in fact that is not true.
Implementers may even be happy to just shrug and say "sure we let you believe it's utf-8", but that is all incidental, none of that was ever agreed or guaranteed.
If an implementer says "nope char is code page XYZ", totally valid, and in fact you can write applications that can change that at runtime.
That problem shows up as clear as days on system that aren't ASCII based. It couldn't work if it wasn't the case.
> > The introduction of char8_t has solved portability problems that char has.
> A problem that doesn't exist on Unix systems and a problem that isn't solved elsewhere (especially Windows) because of the lack of APIs. Therefore, from the *practical* perspective, either you have no problem, or char8_t isn't sufficient for you. The lack of APIs is what Yongwei was complaining about and until most of <string.h>, <locale.h>, <format>, etc. is duplicated for char8_t support, char8_t will have very limited usefulness.
Problems that do absolutely exist on linux systems. I'm not talking about the poor choice of Windows using wchar_t for their native interfaces.
I'm talking about problems like char doesn't have a signedness defined, and that you can change it to be signed or unsigned with a compiler setting, a problem that makes checks like " val < 'A' " ill-formed.
This isn't the case with char8_t, char8_t is unsigned. " val < u8'A' " is well-formed.
-----Original Message-----
From: SG16 <sg16-bounces_at_lists.isocpp.org> On Behalf Of Thiago Macieira via SG16
Sent: Wednesday, July 8, 2026 16:21
To: sg16_at_[hidden]socpp.org
Cc: Thiago Macieira <thiago_at_[hidden]>
Subject: Re: [isocpp-sg16] UTF-8 support status
On Tuesday, 7 July 2026 23:28:24 Pacific Daylight Time Tiago Freire via SG16
wrote:
> If I'm to create a plain transcoding function that converts from utf-8
> to
> utf-16 which is the type used to represent utf-8? char8_t, char should
> not be supported.
That's not correct. Since C++11, char is required to support all UTF-8 code units (that means the minimum size for a byte is 8 bits). The addition of char8_t has not changed the requirement on char.
Therefore, it can't be UB.
Whether the code unit stored in the char makes sense when interpreted under the narrow character set, it's a completely different story.
> The introduction of char8_t has solved portability problems that char has.
A problem that doesn't exist on Unix systems and a problem that isn't solved elsewhere (especially Windows) because of the lack of APIs. Therefore, from the *practical* perspective, either you have no problem, or char8_t isn't sufficient for you. The lack of APIs is what Yongwei was complaining about and until most of <string.h>, <locale.h>, <format>, etc. is duplicated for char8_t support, char8_t will have very limited usefulness.
> Aliasing u8string to string, it wouldn’t just be inconvenient, it
> would actually break code.
That I agree with.
> The lack of IO and formatting support in the standard makes for a
> usability problem. But that is because the formatting and IO in the
> standard are bad, it’s not because char8_t is bad. We should fix the
> bad parts, not throw way the good parts because they don ‘t work with the bad parts.
Agreed.
I don't really care for iostreams. But <format> and all formatters in all other headers need to support at least one of the char8_t/char16_t, and ideally the other one be automatically transcoded as needed.
> Maybe what we need is for a group of people to just go ahead make a
> library that works independent of the standard, have that be widely
> adopted, and when that happens then people will get it. And then
> people will go like “oh, that’s how you are supposed to use it, we want to do like library X”
> and it clicks, and then you can adopt something in the standard
> because everyone gets it.
That's what happened with fmtlib, and it got adopted. That is good.
Except that fmtlib was designed with "char is UTF-8" in mind because it wasn't part of the Standard and could reasonably make that assumption, and that has never been revised.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Principal Engineer - Intel Data Center - Platform & Sys. Eng.
> Therefore, it can't be UB.
> Whether the code unit stored in the char makes sense when interpreted under the narrow character set, it's a completely different story.
First of, isn't the "whether the code unit stored in the char makes sense" the whole point?
Second "that it can fit" doesn't mean "that's how it is interpreted".
How do you explain EBCDIC systems?
There was never a promise that every Unicode character would be translated as utf-8 for char. It can't, otherwise EBCDIC wouldn't work.
`char` lives in a limbo state, when it compiles and runs it must definitely have an encoding, but exactly what that encoding is is not defined anywhere, and worse it can actually be many things at once and nobody knows exactly.
We tend to forget that utf-8 is a hack, it's a hack that was meant to run on systems that work as a superset of ASCII. And it works, so much so that people think the systems they are running on are utf-8, when in fact that is not true.
Implementers may even be happy to just shrug and say "sure we let you believe it's utf-8", but that is all incidental, none of that was ever agreed or guaranteed.
If an implementer says "nope char is code page XYZ", totally valid, and in fact you can write applications that can change that at runtime.
That problem shows up as clear as days on system that aren't ASCII based. It couldn't work if it wasn't the case.
> > The introduction of char8_t has solved portability problems that char has.
> A problem that doesn't exist on Unix systems and a problem that isn't solved elsewhere (especially Windows) because of the lack of APIs. Therefore, from the *practical* perspective, either you have no problem, or char8_t isn't sufficient for you. The lack of APIs is what Yongwei was complaining about and until most of <string.h>, <locale.h>, <format>, etc. is duplicated for char8_t support, char8_t will have very limited usefulness.
Problems that do absolutely exist on linux systems. I'm not talking about the poor choice of Windows using wchar_t for their native interfaces.
I'm talking about problems like char doesn't have a signedness defined, and that you can change it to be signed or unsigned with a compiler setting, a problem that makes checks like " val < 'A' " ill-formed.
This isn't the case with char8_t, char8_t is unsigned. " val < u8'A' " is well-formed.
-----Original Message-----
From: SG16 <sg16-bounces_at_lists.isocpp.org> On Behalf Of Thiago Macieira via SG16
Sent: Wednesday, July 8, 2026 16:21
To: sg16_at_[hidden]socpp.org
Cc: Thiago Macieira <thiago_at_[hidden]>
Subject: Re: [isocpp-sg16] UTF-8 support status
On Tuesday, 7 July 2026 23:28:24 Pacific Daylight Time Tiago Freire via SG16
wrote:
> If I'm to create a plain transcoding function that converts from utf-8
> to
> utf-16 which is the type used to represent utf-8? char8_t, char should
> not be supported.
That's not correct. Since C++11, char is required to support all UTF-8 code units (that means the minimum size for a byte is 8 bits). The addition of char8_t has not changed the requirement on char.
Therefore, it can't be UB.
Whether the code unit stored in the char makes sense when interpreted under the narrow character set, it's a completely different story.
> The introduction of char8_t has solved portability problems that char has.
A problem that doesn't exist on Unix systems and a problem that isn't solved elsewhere (especially Windows) because of the lack of APIs. Therefore, from the *practical* perspective, either you have no problem, or char8_t isn't sufficient for you. The lack of APIs is what Yongwei was complaining about and until most of <string.h>, <locale.h>, <format>, etc. is duplicated for char8_t support, char8_t will have very limited usefulness.
> Aliasing u8string to string, it wouldn’t just be inconvenient, it
> would actually break code.
That I agree with.
> The lack of IO and formatting support in the standard makes for a
> usability problem. But that is because the formatting and IO in the
> standard are bad, it’s not because char8_t is bad. We should fix the
> bad parts, not throw way the good parts because they don ‘t work with the bad parts.
Agreed.
I don't really care for iostreams. But <format> and all formatters in all other headers need to support at least one of the char8_t/char16_t, and ideally the other one be automatically transcoded as needed.
> Maybe what we need is for a group of people to just go ahead make a
> library that works independent of the standard, have that be widely
> adopted, and when that happens then people will get it. And then
> people will go like “oh, that’s how you are supposed to use it, we want to do like library X”
> and it clicks, and then you can adopt something in the standard
> because everyone gets it.
That's what happened with fmtlib, and it got adopted. That is good.
Except that fmtlib was designed with "char is UTF-8" in mind because it wasn't part of the Standard and could reasonably make that assumption, and that has never been revised.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-07-08 15:09:57
