什么保证存储在 char32_t 或 char16_t 到 char 中的 UTF-8 代码单元的 static_cast 会按预期结果?

What guarantees that a static_cast of a UTF-8 code unit stored in a char32_t or char16_t to char will turn out as expected?

使用 C++11 标准时,是否可以保证存储在 char32_tchar16_t 代码点中的 ASCII 字符将正确转换为 char

char32_tchar16_t 都定义为始终无符号 (http://en.cppreference.com/w/cpp/language/types)。但是,char 可能有符号或无符号,具体取决于系统。

我假设 ASCII 字符始终有效:

char32_t original = U'b';
char value = static_cast<char>(original);

但是,UTF-8 代码单元的值以第一位 == 1 开头,并在转换期间使用位掩码从 UTF-32 字符中提取,例如:

char32_t someUtf32CodeUnit = 0x00001EA9;
// Third code-unit of ẩ
char extractedCodeUnit = static_cast<char>(((someUtf32CodeUnit >> 6) & 0x3F) | 0x80);

是否保证所有系统上的转换都将以相同的方式工作(导致所述 UTF-8 代码单元的相同预期位)或者未签名<->签名转换可能会有所不同?

编辑:

据我所知,C++(包括 C++11)对于用于 char 类型的编码是不可知的。唯一的要求 (§3.9.1.1) 是 char 必须能够存储 §2.3 中定义的基本字符集的任何字符。因此,即使是集合外的 ASCII 字符,如 @`,也不能保证存储在 char 中。它们的代码点值显然可以存储,但机器可能会将它们解释为不同的字形(对于 isalpha 和类似的函数)

即使您只是对存储值感兴趣,在您的示例中您尝试 static_cast 一个 int 表达式到 char。如果您的 char 是有符号类型且值大于 127,则结果由实现定义,详情请参阅 this answer