在C11中,对于UTF-16和UTF-32,可移植宽字符类型char16_t
和char32_t
的支持分别为added。
但是,在技术报告中,没有提到这两种类型的字节顺序。
例如,使用gcc-4.8.4
编译时,x86_64计算机上-std=c11
中的以下代码段:
#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
?
答案 0 :(得分:6)
$loop2->rewind_posts();
和char16_t
不保证Unicode编码。 (这是一个C ++特性。)宏char32_t
和__STDC_UTF_16__
分别表示Unicode代码点实际上确定了固定大小的字符值。有关这些宏,请参见C11§6.10.8.2。
(顺便说一下,__STDC_UTF_32__
表示__STDC_ISO_10646__
的相同内容,它还会显示通过wchar_t
实现的Unicode版本。当然,在实践中,编译器只是复制代码从源文件指向目标文件中的字符串,因此不需要了解特定字符。)
鉴于Unicode编码有效,存储在wchar_t
或char16_t
中的代码点值必须与char32_t
和uint_least16_t
具有相同的对象表示,因为它们已定义分别为uint_least32_t
这些类型的别名(C11§7.28)。这与C ++形成鲜明对比,C ++使这些类型不同,但明确要求兼容的对象表示。
结果是肯定的,typedef
和char16_t
没有什么特别之处。它们是平台字节序中的普通整数。
但是,您的测试程序与字节序无关。它只是使用宽字符的值而不检查它们如何映射到内存中的字节。
答案 1 :(得分:2)
但是,在技术报告中,没有提到这两种类型的字节顺序。
事实上。 C标准没有详细说明源文件中多字节字符的表示。
char16_t utf16_str[] = u"十六"; // U+5341 U+516D printf("U+%X U+%X\n", utf_16_str[0], utf_16_str[1]);
会产生 U + 5341 U + 516D 这意味着它是小端的。
但这种行为平台/实现是否依赖:它是否始终遵循平台的字节顺序,或者某些实现可能选择始终在big-endian中实现
char16_t
和char32_t
?
是,行为是依赖于实现,就像你调用它一样。见C11§5.1.1.2:
物理源文件多字节字符以实现定义的方式映射到源字符集(如果需要,引入行尾指示符的换行符)。
也就是说,源代码中的多字节字符是否被视为big endian或little endian是实现定义的。如果可移植性存在问题,我会建议使用像u"\u5341\u516d"
这样的东西。
答案 2 :(得分:0)
UTF-16和UTF-32没有定义字节序。它们通常以主机本机字节顺序编码。这就是为什么可以在字符串的开头插入字节顺序标记(BOM)来指示UTF-16或UTF-32字符串的字节序的原因。