在 C11 中,对可移植宽字符类型 char16_t
和 char32_t
的支持为 added分别用于 UTF-16 和 UTF-32。
但是,在技术报告中,并没有提到这两种类型的字节序。
例如,在我的 x86_64 计算机上使用 -std=c11
编译时,gcc-4.8.4
中的以下代码段:
#include <stdio.h>
#include <uchar.h>
char16_t utf16_str[] = u"十六"; // U+5341 U+516D
unsigned char *chars = (unsigned char *) utf16_str;
printf("Bytes: %X %X %X %X\n", chars[0], chars[1], chars[2], chars[3]);
会产生
Bytes: 41 53 6D 51
这意味着它是小端的。
但是这种行为是否依赖于平台/实现:它是否始终遵守平台的字节序,或者某些实现可能选择始终在 big-endian 中实现 char16_t
和 char32_t
?
最佳答案
char16_t
和 char32_t
不保证 Unicode 编码。 (这是一个 C++ 特性。)宏 __STDC_UTF_16__
和 __STDC_UTF_32__
分别表示 Unicode 代码点实际上决定了固定大小的字符值。有关这些宏,请参见 C11 §6.10.8.2。
(顺便说一下,__STDC_ISO_10646__
对wchar_t
表示同样的意思,它还揭示了通过wchar_t
实现的是哪个Unicode版本。当然,在实践中,编译器只是简单地将源文件中的代码点复制到目标文件中的字符串中,因此它不需要对特定字符了解太多。)
鉴于 Unicode 编码有效,存储在 char16_t
或 char32_t
中的代码点值必须具有与 uint_least16_t
和 uint_least32_t
,因为它们分别被定义为这些类型的 typedef
别名(C11 §7.28)。这再次与 C++ 形成对比,后者使这些类型不同,但明确要求兼容的对象表示。
结果是,是的,char16_t
和 char32_t
并没有什么特别之处。它们是平台字节序中的普通整数。
但是,您的测试程序与字节序无关。它只是使用宽字符的值,而不检查它们如何映射到内存中的字节。
关于char16_t 和 char32_t 字节序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31433324/