Characters in C++: char, wchar_t...
char8_t, an (Explicit) UTF-8 Character Type
Well, it's clear that
char8_tis an 8 bit type. Also, The signedness of char depends on the compiler and the target platform: the defaults for ARM and PowerPC being typically unsigned, the defaults for x86 and x64 signed. whilechar8_tis always unsigned.(Elliott Frisch commented Aug 7, 2019 at 21:28)
Logically, code can assume that a string of char8_t always contains UTF-8 text (barring bugs), whereas it is less safe to assume any particular encoding of a char string without additional knowledge of the environment.
(Miral commented Aug 8, 2019 at 7:31)
Well, there are benefits. The char type, like much of C++'s C heritage is, and has always been annoyingly broken. You do not know whether it's signed or not, and very strictly you do not even know how many bits it has (though 8 is a rather safe bet, there's no guarantee whatsoever). The char8_t type gives both guarantees. Unluckily, nobody was bold enough to simply "fix" the broken original type (which could admittedly break existing code, but so what... modern C++ is incompatible with legacy C++ anyway). Much like nobody could be bothered to make size_t or ptrdiff_t a proper type.
(Damon commented Aug 8, 2019 at 8:48)
@Damon according to this comment, there is no requirement that char8_t is exactly eight bits, so nothing changed in that regard…
(Holger commented Aug 8, 2019 at 9:04)
@Damon C has always guaranteed that char has at least 8 bits. POSIX and most other systems like Windows guarantee that char is exactly 8 bits. But C does not say "Yeah, blah blah POSIX". POSIX incorporates the C standard, not the other way around. And unless C suddenly decides to alienate a huge part of its niche, they're not going to make an exactly eight bit type mandatory, because C is the primary language used to program all the modern embedded/niche hardware which has bytes bigger than eight bits.
(mtraceur commented Apr 23, 2020 at 6:34)
How to Write UTF-8 String Literals in C++
(From http://utf8everywhere.org/)
If you internationalize your software then all non-ASCII strings will be loaded from an external translation database, so it is not a problem.
If you still want to embed a special character you can do it as follows. In C++11 you can do it as:
u8"∃y ∀x ¬(x ≺ y)"
With compilers that do not support ‘u8’ you can hard-code the UTF-8 code units as follows:
"\xE2\x88\x83y \xE2\x88\x80x \xC2\xAC(x \xE2\x89\xBA y)"
However the most straightforward way is to just write the string as-is and save the source file encoded in UTF-8:
"∃y ∀x ¬(x ≺ y)"
Wide Characters with wchar_t
A wide char is similar to the char data type, except that wide chars take up twice the space and can take on values in a far wider range as a result. char can only take one of 256 values, which corresponds to entries in the ASCII table. On the other hand, a wide char can take on 65536 values which corresponds to UNICODE values, which is a recent international standard which allows for the encoding of characters for virtually all languages and commonly used symbols.
Some points:
- Just like the type for character constants is
char, the type for wide character iswchar_t. - This data type occupies 2 or 4 bytes depending on the compiler being used.
- Mostly the
wchar_tdatatype is used when international languages like Japanese are used.
Below is a simple C++ program to show how wchar_t is used:
// An example in C++ demonstrating wchar_t
#include <iostream>
using namespace std;
int main()
{
wchar_t w = L'A';
cout << "Wide character value:: " << w << endl ;
cout << "Size of the wide char is:: " << sizeof(w);
return 0;
}>
When should we use wchar_t. The site utf8everywhere.org recommends converting from wchar_t to char (UTF-16 to UTF-8) as soon as you receive it from any library, and converting back when you need to pass strings to it. Therefore, always use char except when an API requires you to pass or receive wchar_t. The rationale is that UTF-8 (matching C/C++ char) is good enough for all use cases but a select few.