这里有一些简单的代码:
#include <iostream>
#include <cstdint>
int main()
{
const unsigned char utf8_string[] = u8"\xA0";
std::cout << std::hex << "Size: " << sizeof(utf8_string) << std::endl;
for (int i=0; i < sizeof(utf8_string); i++) {
std::cout << std::hex << (uint16_t)utf8_string[i] << std::endl;
}
}
在MSVC和GCC中,我看到了不同的行为。
MSVC将"\xA0"
视为未编码的Unicode序列,并将其编码为UTF-8。因此,在MSVC中输出为:
C2A0
这正确地编码为UTF-8 Unicode符号U+00A0
。
但是在GCC的情况下,什么也没有发生。它将字符串视为简单的字节。即使我在字符串文字之前删除u8
,也没有变化。
如果将字符串设置为u8"\u00A0";
,则两个编译器都使用输出C2A0
进行UTF8编码。
为什么编译器表现不同,哪一个才是正确的?
用于测试的软件:
GCC 8.3.0
MSVC 19.00.23506
C++11
g++
和clang
上,我得到了这个:大小: 2 a0 0
。 - brc-ddu8
的输出是标准的,必须是 UTF-8。但u8
输入的解释可能不是标准的。\uXXXX
和\UXXXXXXXX
的行为是标准的,它们必须被解释为一个代码点。但是\xXX
的解释有点更加实现相关。\xA0
可以被解释为一个单独的char
0xA0
,或者它可以被扩展为代码点 U+00A0 然后编码为 2 个char
0xC2 0xA0
。你会看到这两种行为。 - Remy LebeauU8'\xA0'
是不合法的(因为该代码点不能用单个UTF-8代码单元表示),因此我预计带有这种字面值的字符字符串也会导致一个不合法的程序。 - 1201ProgramAlarm