char16_t和char32_t endianness

时间:2015-07-15 14:32:54

标签: c endianness c11 char16-t char32-t

在C11中,对于UTF-16和UTF-32,可移植宽字符类型char16_tchar32_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_tchar32_t

3 个答案:

答案 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_tchar16_t中的代码点值必须与char32_tuint_least16_t具有相同的对象表示,因为它们已定义分别为uint_least32_t这些类型的别名(C11§7.28)。这与C ++形成鲜明对比,C ++使这些类型不同,但明确要求兼容的对象表示。

结果是肯定的,typedefchar16_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_tchar32_t

,行为是依赖于实现,就像你调用它一样。见C11§5.1.1.2:

  

物理源文件多字节字符以实​​现定义的方式映射到源字符集(如果需要,引入行尾指示符的换行符)。

也就是说,源代码中的多字节字符是否被视为big endian或little endian是实现定义的。如果可移植性存在问题,我会建议使用像u"\u5341\u516d"这样的东西。

答案 2 :(得分:0)

UTF-16和UTF-32没有定义字节序。它们通常以主机本机字节顺序编码。这就是为什么可以在字符串的开头插入字节顺序标记(BOM)来指示UTF-16或UTF-32字符串的字节序的原因。