什么构成“有效”C 标识符?

2024-05-01

根据 @Zaibis 的建议(并且与我自己的相关)answer to 宏名称的有效字符是什么? https://stackoverflow.com/a/34315237/547214, 也g++ 不允许的标识符中的????(和其他 Unicode 字符) https://stackoverflow.com/questions/12692067/and-other-unicode-characters-in-identifiers-not-allowed-by-g))...

clang 允许使用很多“疯狂”的字符.. 尽管我一直在努力寻找很多押韵或理由 - 至于为什么有些是允许的 (???? ϟ ツ ⌘ ☁ ½),而另一些则不允许 (▶︎ ∀ ★ ©)。

例如,以下全部编译 A-OK (clang-700.1.76)

#define ????  ?:          // OK (Pile of poo)
#define  ■  @end        // OK (HALFWIDTH BLACK SQUARE)
#define ????  @interface  // OK (NEGATIVE SQUARED LATIN CAPITAL LETTER K)
#define P  @protocol   // OK (FULLWIDTH LATIN CAPITAL LETTER P)

然而以下所有结果都会导致相同的编译器错误......

Macro name must be an identifier.

#define  ☎     TEL
#define ❌     NO
#define  ⇧     UP
#define  〓    ==
#define  ????   APPLE

Clang 的文档提到了这个问题 http://llvm.org/releases/3.3/tools/clang/docs/ReleaseNotes.html#major-new-features,仅说明...

...对 C99 和 C++ 中的扩展标识符的支持。此功能允许标识符包含某些由现行语言标准指定的 Unicode 字符;这些字符可以使用 UTF-8 编码直接写入源文件中,或者使用通用字符名称(\u00E0、\U000000E0)进行引用。

所以,我想我在问..什么is“活动语言标准”,以及如何找到合法标识符的权威来源。

我创建了以下代码 http://git.io/v01Pv只是为了看看什么Clang https://en.wikipedia.org/wiki/Clang就可以了。在测试的约 63488 个可能的标识符中,有 23 个发出警告,9506 个生成错误。这样就剩下近 54,000 个有效字符可用于标识符。当然足够了,但是谁被削减了呢?为什么?


正如其他人所提到的,附件 DISO/IEC 9899:2011 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf列出了 C11 中通用字符名称有效的字符的十六进制值。 (我不会在这里重复。)我一直在寻找“为什么”选择这个列表的答案。

字符集标准

首先,有两个相关标准定义了一组字符:ISO/IEC 10646 http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=63182(定义UCS https://en.wikipedia.org/wiki/Universal_Coded_Character_Set) and Unicode http://unicode.org/。为了进一步混淆(或简化)事情,它们都定义了相同的字符因为 ISO 和 Unicode 保留了它们同步的 http://unicode.org/faq/unicode_iso.html。 UCS 本质上只是一个将值与一组字符(“曲目”)相关联的字符映射,而 Unicode 还提供了进一步的定义,例如如何按字母排序顺序比较字符串(整理 http://unicode.org/reports/tr10/),哪些代码点表示“规范等效”字符(正常化 http://unicode.org/faq/normalization.html),和一个双向算法 http://unicode.org/reports/tr9/了解如何处理从右向左书写的语言中的字符等等。

C 中的通用字符名称

通用字符名称(UCN)是C99(ISO/IEC 9899:1999)中新添加的功能。在“国际标准的基本原理---编程语言---C”中(修订版 2,1999 年 10 月 http://www.open-std.org/JTC1/SC22/WG14/www/docs/n897.pdf),目的是“允许在标识符、字符串文字和字符常量中使用任何‘本地’字符,同时保留 C 的可移植性目标”(第 5.2.1 节)。本节继续讨论如何在 C 中对这些字符进行编码(\U and \u形式与多字节字符或本机编码)以及如何处理它的策略模型(第 14 页,请参阅PDF http://www.open-std.org/JTC1/SC22/WG14/www/docs/n897.pdf第 22 页)。

基本原理

我希望同样1999年的“理由”文件 http://www.open-std.org/JTC1/SC22/WG14/www/docs/n897.pdf将给出为什么每个扩展字符范围被选择为 C99 的 UCN 可接受的原因。理由附件一的全部内容是:

附件一 标识符的通用字符名称(规范)

C9X的一项新功能。

这并不是什么大道理。他们甚至不知道C标准会在哪一年发布,所以就简单地称为“C9X”。后来的一个2003年的理由文件 http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf稍微更有启发性:

附录 D 标识符的通用字符名称(规范)

C99 的新功能。

目的是与 ISO/IEC TR 10176 保持同步。

ISO/IEC TR 10176 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=37765就是《程序设计语言标准编写指南》。它基本上是编写编程语言标准的人的指南。它包括在编程语言中使用字符集的指南以及“用户定义标识符的推荐扩展指令集”(附录 A)。但引用 2003 年理由文件中的这句话只是“保持最新的意图”,而不是严格遵守 TR 10176 的承诺。

有一个公开的ISO/IEC TR 10176:2003 表 http://www.iso.org/ittf/ISOIEC_TR_10176_2003_Table.txt的字符。字符值参考 ISO 10646。该表将多种语言的字符范围分类为“大写”Lu; “小写”Ll; “数字,十进制数字”Nd、“标点符号、连接符”Pc;等等。这样的分类对于编程语言有什么用处应该很清楚。

重要提醒是,TR 10176 是一份技术报告,而不是标准。我在论坛和与其他编程语言(例如 Ada、COBOL 和 D 语言)相关的文档中发现了一些对它的引用。大部分讨论都是关于这些语言的标准应在多大程度上遵循 TR 10176(不是标准),并抱怨 TR 10176 落后于 ISO 10646 的更新。

也许最有启发性的是文档WG21/N3146 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3146.html:“C 和 C++ 扩展标识符字符的建议。”它始于 2010 年向标准机构提出的一项评论,建议对标识符的首字符进行限制。它提到了有关 C 引用 TR 10176 的类似抱怨,并根据以下限制提出了关于应允许哪些字符作为标识符的初始字符的建议Unicode 的标识符和模式语法 http://www.unicode.org/reports/tr31/tr31-11.html#Alternative_Identifier_Syntax and XML 的常见语法结构 http://www.w3.org/TR/2008/REC-xml-20081126/#sec-common-syn。 WG21/N3146 给出了后来出现在 C11 标准中的拟议措辞ISO/IEC 9899:2011 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf。文档末尾有一个表格,可帮助阐明所选的字符范围。

C11 中允许和不允许的字符

以下是范围的编译列表extended标识符字符。这boldface范围是 C11 中给出的范围(ISO/IEC 9899:2011 附录 D http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)。添加了一些关于斜体字 ranges 未列入C11(即不允许)。它们要么被标记在WG21/N3146 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3146.html不允许Unicode 的 UAX#31 http://www.unicode.org/reports/tr31/tr31-11.html#Alternative_Identifier_Syntax or XML 的常见语法结构 http://www.w3.org/TR/2008/REC-xml-20081126/#sec-common-syn,或被其他一些评论禁止。

00A8、00AA、00AD、00AF、00B2-00B5、00C0-00D6、00D8-00F6、00F8-00FF:(各种字符,例如阴性 ª 和阳性 º 序数指示符、带变音符号的元音、数字字符(例如上标数字、分数等)

(之前的空白): 全部禁止UAX31 http://www.unicode.org/reports/tr31/tr31-11.html#Alternative_Identifier_Syntax and/or XML http://www.w3.org/TR/2008/REC-xml-20081126/#sec-common-syn。 (一般为标点符号,如 «»、货币符号 ¥£、数学运算符 ×÷ 等)

0100-167F:(拉丁语、希腊语、西里尔语、阿拉伯语、泰语、埃塞俄比亚语等——许多其他)

1680:“Ogham 块包含特定于脚本的空间: ”

1681-180D:(奥甘语、他加禄语、蒙古语等)

180E:“蒙古文块包含特定于脚本的空间”

180F-1FFF:(更多语言...语音、扩展拉丁语和希腊语等)

2000: 启动“常规标点符号”块,但有些是允许的:

200B−200D、202A−202E、203F−2040、2054、2060−206F:(选自“常规标点符号”块)

2070−218F:“上标和下标、货币符号、符号组合变音标记、字母符号、数字形式”

2190-245F:“箭头、数学运算符、杂项技术、控制图片、光学字符识别”

2460-24FF:“附上字母数字”

2500:开始“方框图、块元素、几何形状”等。

2776-2793:(一些标志和圆圈标志)

2794-2BFF:(不同的符号集、数学符号、箭头、盲文图案等)

2C00-2DFF, 2E80-2FFF:“格拉哥里语、拉丁语扩展-C、科普特语、格鲁吉亚语补充、蒂菲纳语、埃塞俄比亚语扩展、西里尔语扩展-A”(也是 CJK 部首补充)

3000: (“CJK 符号和标点符号”的开头,允许一些选择)

3004-3007, 3021-302F, 3031-303F:(允许“CJK 符号和标点符号”)

3040-D7FF:“平假名、片假名”、更多CJK表意文字、部首等。

D800-F8FF:(这将启动High http://unicode.org/charts/PDF/UD800.pdf和低代理区域(编码所需的数字空间),以及私人使用 http://unicode.org/charts/PDF/UE000.pdf)

F900-FD3D、FD40-FDCF、FDF0-FE44、FE47-FFFD:选自“中日韩兼容表意文字”、“阿拉伯语表示形式”等。10000−1FFFD、20000−2FFFD、30000−3FFFD、40000−4FFFD、50000−5FFFD、 60000−6FFFD、70000−7FFFD、80000−8FFFD、90000−9FFFD、A0000−AFFFD、 B0000-BFFFD、C0000-CFFFD、D0000-DFFFD、E0000-EFFFD: WG21/N3146 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3146.html给出了这些最终范围的基本原理:

补充私人使用区从 F0000 延伸至 10FFFF;两个都[AltId] http://www.unicode.org/reports/tr31/tr31-11.html#Alternative_Identifier_Syntax and [XML2008] http://www.w3.org/TR/2008/REC-xml-20081126/#sec-common-syn禁止使用该范围内的字符。

此外,[AltId] http://www.unicode.org/reports/tr31/tr31-11.html#Alternative_Identifier_Syntax对于任何 P 值,不允许将每个平面的最后两个代码位置作为非字符,即 PFFFE 或 PFFFF 形式的每个位置

“最初不允许的字符范围”来自C11 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf附件 D.2 是0300−036F、1DC0−1DFF、20D0−20FF、FE20−FE2F.

有了这个WG21/N3146 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3146.html放在附件D旁边C11标准 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf,可以推断出很多关于它们如何排列的信息。例如,数学运算符和标点符号似乎是不允许的。我希望这有助于了解“为什么”或“如何”选择允许的字符。


太长了;版本

  • 合法标识符字符的权威来源是 C11 标准ISO/IEC 9899:2011 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf(见附件 D)。
  • 该列表基于技术报告,ISO/IEC TR 10176 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=37765,但与修改 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3146.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么构成“有效”C 标识符? 的相关文章

随机推荐