为什么 C++ 语言禁止使用某些可打印字符的 ALT 代码作为标识符?

Fra*_*ler 2 c++ unicode language-design identifier alt-codes

考虑以下代码片段:

\n
struct vec2 {\n    int x;\n    int y;\n};\n\nconstexpr vec2 Up{0,1};\nconstexpr vec2 Down{0,-1};\nconstexpr vec2 Left{-1,0};\nconstexpr vec2 Right{1,0};\n
Run Code Online (Sandbox Code Playgroud)\n

上面的代码片段编译没有问题,并且被认为是有效且正确的语法。

\n

现在考虑以下被视为非法或无效语法的演示:

\n
struct vec2 {\n    int x;\n    int y;\n};\n\nconstexpr vec2 \xe2\x86\x91{0,1};   // Windows Alt Code: Alt+24 \nconstexpr vec2 \xe2\x86\x93{0,-1};  // Windows Alt Code: Alt+25\nconstexpr vec2 \xe2\x86\x90{-1,0};  // Windows Alt Code: Alt+27\nconstexpr vec2 \xe2\x86\x92{1,0};   // Windows Alt Code: Alt+26\n
Run Code Online (Sandbox Code Playgroud)\n

编译器资源管理器给出以下编译器错误:

\n
    \n
  • 对于 x64 msvc v19.latest 它会给出编译器错误:C3872
  • \n
  • 对于 x86-64 gcc(trunk) 状态:扩展字符不是有效标识符
  • \n
  • 对于 x86-64(主干)状态:意外字符 - 不合格的 id
  • \n
\n

我知道它们不合格并且作为标识符无效。我只是想弄清楚为什么 C++ 语言禁止它们,标准对它们有什么规定,以及在语言标准中可以在哪里找到它们。阻止这些成为有效标识符的原因是什么?

\n

use*_*522 5

箭头字符的代码点值为 U+2190 到 U+2193。

标识符中允许的 UCS/Unicode 代码点在 C++17 和 C++20的 [lex.name] 表 2中列出(此处链接为 C++17 之前的草案 N4659),见附录 E所有先前版本的标准(从 C++98 开始),并参考C++23 的[lex.name]/1中的 Unicode 标准附件 #31(在此处链接当前草案)。

在这些中,范围都没有被列为允许的,因此编译器应该将字符/字符串文字之外的它们解析为非空白单字符预处理器标记,然后应将其作为格式错误的标记拒绝。

代码点列表源自JTC1/SC22/WG20的ISO/IEC 10176“编程语言标准准备指南”。这里有 WG20 的文件注册。

快速浏览一下,我找不到任何关于具体包含箭头符号的范围的可访问讨论,但据我所知,这里的意图并不是一般地扩展由数字、拉丁字母和 组成的传统标识符语法,而只是_扩展将此语法的“字母”部分国际化,以允许在本机脚本中编写标识符,即除了传统代码点范围之外还允许的代码点范围代表(大部分)不同语言的字母或脚本的其他部分,但不包括标点符号或符号。

我认为没有太多支持将字符(序列)包含为标识符,这些字符在视觉上更有可能被视为标点符号、运算符或符号。特别是 C++23 中对 UAX #31 的更改导致标识符中不允许使用表情符号。根据相关提案P1949,表情符号之所以被允许,是因为最初指定的标识符范围在指定时尚未分配。