我在新的 C++ 标准中找到
2.11 Identifiers [lex.name]
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined character
附加文本
标识符是任意长的字母和数字序列。标识符中的每个通用字符名称应指定一个字符,其在 ISO 10646 中的编码属于 E.1 中规定的范围之一。[...]
我不能完全理解这意味着什么。例如,从旧的标准中,我习惯于写一个“通用字符名称” \u89ab
。但是在标识符中使用那些......?真的吗?
新标准是否对 Unicode 更开放?而且我没有提到新的Literal Types "uHello \u89ab thing"u32
,我想我理解了那些。但:
- (便携式)源代码可以采用任何 unicode 编码,如 UTF-8、UTF-16 或任何(如何定义)代码页?
- 我可以
\u1234
在其中写一个标识符吗myfu\u1234ntion
(无论出于何种目的) 或者我可以使用 unicode 在 ICU 中定义的“字符名称”,即
const auto x = "German Braunb\U{LOWERCASE LETTER A WITH DIARESIS}r."u32;
甚至在源本身的标识符中?那将是一种享受......咳嗽......
我认为所有这些问题的答案是否定的,但我无法将其可靠地映射到标准中的措辞...... :-)
编辑:我发现“2.2 翻译阶段 [lex.phases]”,第 1 阶段:
如有必要,物理源文件字符以实现定义的方式映射到基本源字符集 [...]。接受的物理源文件字符集是实现定义的。[...] 任何不在基本源字符集 (2.3) 中的源文件字符都将替换为指定该字符的通用字符名称。(实现可以使用任何内部编码,只要在源文件中遇到的实际扩展字符,以及在源文件中表示为通用字符名称的相同扩展字符(即,使用 \uXXXX 表示法)是等效处理,除非此替换在原始字符串文字中恢复。)
通过阅读本文,我现在认为,编译器可以选择接受 UTF-8、UTF-16 或它希望的任何代码页(通过元信息或用户配置)。在第 1 阶段,它将其转换为 ASCII 形式(“基本源字符集”),然后将 Unicode 字符替换为其\uNNNN
符号(或者编译器可以选择继续以它的 Unicode 表示形式工作,但必须确保它\uNNNN
以相同的方式处理另一个。
你怎么看?