Thanks, I could have sworn it was all narrow character types & byte.
It looks like I've escaped problems so far since nobody actually uses signed char for that. Including me, topic post notwithstanding - I either use plain char or u8.
To me, JLborges post implies that it's allowed for uint8_t to differ from unsigned char. Do you guys know of any implementations where there's a difference? Or are they always the same in practice?
I remember reading a few days ago about a DSP or some other embedded platform where char, short, int, and std::int16_t were all the same type. char is just the addressable unit of memory (i.e. the byte), which can be larger or smaller than an octet.
It seems like GCC allows signed char to alias other types just like char and unsigned char.
I think it would have been a good thing if std::(u)int8_t had been implemented as separate types that were not allowed to alias because it would have lead to more efficient code.
C++20 added the non-aliasing unsigned char-sized type named "char8_t" but it's intended to be used to store UTF-8 string data. But if the standard doesn't add new non-aliasing 8-bit types (that are non-aliasing in practice, not just on paper) then I'm afraid people will be tempted to start using char8_t as a regular integer type.
> it's allowed for uint8_t to differ from unsigned char
An implementation with CHAR_BIT == 8 and std::signed_integral<char> == false,
(in theory) may define using uint8_t = char ; // unsigned integer type with width of exactly 8 bits
using i8 = signed char;
Since I want to alias stuff with i8*.
The standard only guarantees you can do that with char, unsigned char and std::byte.
VS alias int8_t to signed char. As the sign-ness of char can be changed by a compiler option, alias to char would also mean that the sign-ness of the alias would also depend upon compiler option. So if signed char couldn't be used and i8 was alias for char, then i8 could be either signed or unsigned...
This is different for int etc. int means signed int.
Ok good point. That makes the choice of char even less viable for implementations where those compiler options exist.
GCC and Clang have -funsigned-char and -fsigned-char too.
It follows that int8_t* is quite unlikely to alias without some language extension being involved.
It's also 'interesting' that irrespective of how char is defined by the compiler, std::same_as fails when comparing with either signed char or unsigned char. It only succeeds when comparing char with char!
Yes I know. I've used C++ since before C++98 - but hands up at the back for those that didn't. It's not something I think is intuitive especially considering int/signed int...
unsigned char value: as int 200 as unsigned 200
signed char value: as int -56 as unsigned 4294967240
which helps to explain the casting required for the cctype c functions' args. So if you have char as unsigned by the compiler, you don't need all that nasty casting for the args to these functions (although you still do for the return value).