Comment by ChrisSD

20 hours ago

`char8_t` is probably one of the more baffling blunders of the standards committee.

there is no guarantee `char` is 8 bits, nor that it represents text, or even a particular encoding.

If your codebase has those guarantees, go ahead and use it.

  • > there is no guarantee `char` is 8 bits, nor that it represents text, or even a particular encoding.

    True, but sizeof(char) is defined to be 1. In section 7.6.2.5:

    "The result of sizeof applied to any of the narrow character types is 1"

    In fact, char and associated types are the only types in the standard where the size is not implementation-defined.

    So the only way that a C++ implementation can conform to the standard and have a char type that is not 8 bits is if the size of a byte is not 8 bits. There are historical systems that meet that constraint but no modern systems that I am aware of.

    [1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n49...

  • char8_t also isn't guaranteed to be 8-bits, because sizeof(char) == 1 and sizeof(char8_t) >= 1. On a platform where char is 16 bits, char8_t will be 16 bits as well

    The cpp standard explicitly says that it has the same size, typed, signedness and alignment as unsigned char, but its a distinct type. So its pretty useless, and badly named

    • Wouldn't it be rather the case that char8_t just wouldn't exist on that platform? At least that's the case with the uintN_t types, they are just not available everywhere. If you want something that is always available you need to use uintN_least_t or uintN_fast_t.

  • There's no guarantee char8_t is 8 bits either, it's only guaranteed to be at least 8 bits.

    • > There's no guarantee char8_t is 8 bits either, it's only guaranteed to be at least 8 bits.

      Have you read the standard? It says: "The result of sizeof applied to any of the narrow character types is 1." Here, "narrow character types" means char and char8_t. So technically they aren't guaranteed to be 8 bits, but they are guaranteed to be one byte.

      1 reply →

  • That's where the standard should come in and say something like "starting with C++26 char is always 1 byte and signed. std::string is always UTF-8" Done, fixed unicode in C++.

    But instead we get this mess. I guess it's because there's too much Microsoft in the standard and they are the only ones not having UTF-8 everywhere in Windows yet.

  • Related: in C at least (C++ standards are tl;dr), type names like `int32_t` are not required to exist. Most uses, in portable code, should be `int_least32_t`, which is required.

  • char on linux arm is unsigned, makes for fun surprises when you only ever dealt with x86 and assumed char to be signed everywhere.

    • This bit us in Chromium. We at least discussed forcing the compiler to use unsigned char on all platforms; I don't recall if that actually happened.

      2 replies →