GCC 和 MSVC 中的 C++ utf-8 文字

too*_*zzy 7 c++ unicode gcc utf-8 visual-c++

这里我有一些简单的代码:

#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;
          }
    }
Run Code Online (Sandbox Code Playgroud)

我在这里看到 MSVC 和 GCC 的不同行为。MSVC 认为"\xA0"未编码的 unicode 序列,并将其编码为 utf-8。所以在 MSVC 中,输出是:

C2A0

这是在 utf8 unicode 符号中正确编码的U+00A0

但是在 GCC 的情况下,什么也没有发生。它将字符串视为简单的字节。即使我u8在字符串文字之前删除也没有变化。

这两种编译器编码与输出UTF8C2A0如果字符串设定为:u8"\u00A0";

为什么编译器的行为不同,哪个实际上是正确的?

用于测试的软件:

海湾合作委员会 8.3.0

MSVC 19.00.23506

C++ 11

Atn*_*nNn 3

他们都错了。

据我所知,C++17 标准在这里表示:

窄字符串文字的大小是转义序列和其他字符的总数,加上每个通用字符名称的多字节编码的至少 1,再加上终止 '\0' 的 1。

尽管还有其他提示,但这似乎是最有力的迹象,表明转义序列不是多字节的,并且 MSVC 的行为是错误的。

目前有一些相关票证被标记为“正在调查”:

然而,它还在这里提到了 UTF-8 文字:

如果该值无法用单个 UTF-8 代码单元表示,则该程序格式错误。

由于0xA0不是有效的 UTF-8 字符,因此程序不应编译。

注意:

  • 以 开头的 UTF-8 文字u8被定义为窄文字。
  • \xA0是一个转义序列
  • \u00A0被认为是通用字符名称而不是转义序列