"be representable in execution character set" 是什么意思?

What does "be representable in execution character set" mean?

字符文字的类型由以下规则指定:

A character literal that does not begin with u8, u, U, or L is an ordinary character literal. An ordinary character literal that contains a single c-char representable in the execution character set has type char, with value equal to the numerical value of the encoding of the c-char in the execution character set. An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.

所以考虑下面的例子

#include <iostream>
int main(){
    auto c = '\u0080';
    std::cout<< typeid(c).name();
}

c的类型是int(由GCC报告)。为什么c的类型是int

根据c-char的语法,定义为:

c-char:

  • any member of the source character set except the single-quote ', backslash , or new-line character
  • escape-sequence
  • universal-character-name

在此示例中,\u0080 是一个 通用字符名称 ,它是单个 c-char。所以普通字符文字 '\u0080' 不包含超过一个 c-char。 GCC默认的执行字符集是UTF-8。这意味着,\u0080 完全可以用 UTF-8 集表示。为什么 GCC 将 c 的类型指定为 int?虽然我知道这样的代码点值不能用 char 对象表示,但上面的规则并不是这样说的。是 GCC 错误还是我误解了什么?如何解释“在执行字符集中可表示”?

The default execution character set of GCC is UTF-8.

这就是问题所在。也就是说,这不是真的。或者至少,不是 C++ 标准所指的方式。

标准将“基本字符集”定义为 96 个不同字符的集合。但是,它没有为它们定义编码。也就是说,字符“A”是“基本字符集”的一部分。但未指定该字符的

标准在定义“基本执行字符集”时,在基本集上增加了一些字符,但也定义了字符到值的映射。然而,除了 NUL 字符为 0(并且数字必须以连续序列编码)之外,它允许实现自行决定映射是什么。

问题是:根据该术语的任何合理定义,UTF-8 都不是“字符集”。

Unicode是一个字符集;它定义了一系列存在的字符及其含义。它还为 Unicode 字符集中的每个字符一个唯一的数值(一个 Unicode 代码点)。

UTF-8 是...不是那个。 UTF-8 是一种 encoding 字符的方案,通常在 Unicode 字符集中(尽管它并不挑剔;它可以用于任何 21 位数字,并且可以扩展到 32-位)。

所以 when GCC's documentation 说:

[The execution character set] is under control of the user; the default is UTF-8, matching the source character set.

这种说法没有意义,因为如前所述,UTF-8 是一种文本编码,而不是字符集。

GCC 的文档(可能还有 GCC 的命令行选项)似乎发生了什么,他们将“执行字符集”的概念与“窄字符编码方案”混为一谈。 UTF-8 是 GCC 默认编码窄字符串的方式。但这与说它的“执行字符集”是什么不同。

即可以使用UTF-8编码只是C++定义的基本执行字符集。使用 UTF-8 作为您的窄字符编码方案与您的执行字符集无关。

请注意 Visual Studio 和 makes a similar conflation of the two concepts 有一个名称相似的选项。他们称其为“执行字符集”,但他们将选项的 行为 解释为:

The execution character set is the encoding used for the text of your program that is input to the compilation phase after all preprocessing steps.

那么...是什么 GCC 的执行字符集?好吧,由于他们的文档混淆了“执行字符集”和“窄字符串编码”,因此几乎不可能知道。

那么标准 要求 GCC 的行为是什么?好吧,把你引用的规则转过来。字符文字中的单个通用字符名称将是 charint,并且只有当通用字符名称命名字符 时才会是后者not 在执行字符集中。因此,系统的执行字符集不可能包含比 char 允许的字符更多的字符。

也就是说,GCC的执行字符集不能完整的是Unicode。它必须是 Unicode 的某个子集。它可以选择它是 Unicode 的子集,其 UTF-8 编码占用 1 char,但它已经尽可能大了。


虽然我将此归结为 GCC 的问题,但它在技术上也是 C++ 规范中的一个问题。您引用的段落 also 将编码机制(即:char 的含义)与执行字符集(即:可存储哪些字符)混为一谈。

此问题已 recognized and addressed 添加以下措辞:

A non-encodable character literal is a character-literal whose c-char-sequence consists of a single c-char that is not a numeric-escape-sequence and that specifies a character that either lacks representation in the literal's associated character encoding or that cannot be encoded as a single code unit. A multicharacter literal is a character-literal whose c-char-sequence consists of more than one c-char. The encoding-prefix of a non-encodable character literal or a multicharacter literal shall be absent or L. Such character-literals are conditionally-supported.

由于这些建议(并被接受)为 CWG 问题的解决方案,因此它们也追溯适用于标准的先前版本。