C++ 11中的Unicode标识符和源代码?

tow*_*owi 12 unicode syntax c++11

我在新的C++标准中找到了

2.11 Identifiers                  [lex.name]
identifier:
    identifier-nondigit
    identifier identifier-nondigit
    identifier digit
identifier-nondigit:
    nondigit
    universal-character-name
    other implementation-defined character
Run Code Online (Sandbox Code Playgroud)

附加文字

标识符是任意长的字母和数字序列.标识符中的每个通用字符名称应指定一个字符,其ISO 10646中的编码属于E.1中规定的范围之一.[...]

我无法理解这意味着什么.从旧的标准我习惯\u89ab,例如写一个"通用字符名称" .但是在标识符中使用那些......?真?

新标准对Unicode更加开放吗?而且我没有提到新的文字类型 "uHello \u89ab thing"u32,我想我理解了这些.但:

  • Can(可移植)源代码可以是任何unicode编码,如UTF-8,UTF-16或任何(如何定义的)代码页?
  • 我可以\u1234在里面写一个标识符myfu\u1234ntion(出于任何目的)
  • 或者我可以使用unicode在ICU中定义的"字符名称",即

    const auto x = "German Braunb\U{LOWERCASE LETTER A WITH DIARESIS}r."u32;
    
    Run Code Online (Sandbox Code Playgroud)

    甚至在源本身的标识符中?这将是一种享受...... 咳嗽 ......

我认为答案给所有thise问题是没有,但我不能在标准的可靠映射这措辞... :-)

编辑:我找到了"2.2翻译阶段[lex.phases]",第1阶段:

如果需要,物理源文件字符以实现定义的方式映射到基本源字符集[...].接受的物理源文件字符集是实现定义的.[...]任何不在基本源字符集(2.3)中的源文件字符都将替换为指定该字符的通用字符名称.(实现可以使用任何内部编码,只要在源文件中遇到实际扩展字符,并且在源文件中表示为与通用字符名称相同的扩展字符(即,使用\ uXXXX表示法),处理等效,除非在原始字符串文字中还原此替换.)

通过阅读本文,我现在认为,编译器可以选择接受UTF-8,UTF-16或它希望的任何代码页(通过元信息或用户配置).在阶段1中,它将其转换为ASCII格式("基本源字符集"),然后用其\uNNNN符号替换Unicode字符(或者编译器可以选择继续以其Unicode表示形式工作,但不得不确保它\uNNNN以相同的方式处理另一个.

你怎么看?

bam*_*s53 12

新标准对Unicode更加开放吗?

关于允许标识符中的通用字符名称,答案是否定的; 在C99和C++ 98中允许使用UCN标识符.然而,编译器直到最近才实现该特定要求.Clang 3.3我认为引入了对此的支持,GCC已经为此做了一段时间的实验性功能.Herb Sutter在他的Build 2013演讲"C++的未来"中也提到过,这个特性在某些时候也会出现在VC++中.(尽管IIRC Herb将其称为C++ 11特性;它实际上是C++ 98特性.)

不期望标识符将使用UCN编写.相反,预期的行为是使用源编码编写所需的字符.例如,源代码如下:

long pörk;
Run Code Online (Sandbox Code Playgroud)

不:

long p\u00F6rk;
Run Code Online (Sandbox Code Playgroud)

然而,UCN也可用于其他目的; 编译器并不都需要接受相同的源编码,但现代编译器都支持一些编码方案,其中至少基本源字符具有相同的编码(即,现代编译器都支持某些ASCII兼容编码).

UCN允许您只使用基本字符编写源代码,但仍然可以命名扩展字符.这在例如在源代码中编写字符串文字"°"时非常有用,它将被编译为CP1252和UTF-8:

char const *degree_sign = "\u00b0";
Run Code Online (Sandbox Code Playgroud)

只要编译器至少共享基本字符的相同编码,即使源编码不同,此字符串文字也会编码到多个编译器上的相应执行编码中.

Can(可移植)源代码可以是任何unicode编码,如UTF-8,UTF-16或任何(如何定义的)代码页?

标准不要求它,但大多数编译器都会接受UTF-8源代码.Clang 支持UTF-8源(虽然它对字符和字符串文字中的非UTF-8数据有一定的兼容性),gcc允许指定源编码并包含对UTF-8的支持,VC++将猜测编码并且可以猜测UTF-8.

(更新:VS2015现在提供了一个选项来强制源和执行字符集是UTF-8).

我可以用\ u1234在其中写一个标识符myfu\u1234ntion(出于任何目的)

是的,规范要求这样做,尽管我说并非所有编译器都实现了这个要求.

或者我可以使用unicode在ICU中定义的"字符名称",即

const auto x = "German Braunb\U{LOWERCASE LETTER A WITH DIARESIS}r."u32;
Run Code Online (Sandbox Code Playgroud)

不,您不能使用Unicode长名称.

甚至在源本身的标识符中?这将是一种享受......咳嗽......

如果编译器支持包含所需扩展字符的源代码编码,那么字面上在源中写入的字符必须与等效的UCN完全相同.所以是的,如果您使用支持C++规范的这个要求的编译器,那么您可以直接在源代码中编写其源字符集中的任何字符,而无需编写UCN.