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

| 我在新的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。 [...] 我不太理解这是什么意思。从旧的标准输入法开始,我习惯于将“通用字符名称”写为“ 1”。但是在标识符中使用那些...?真? 新标准对Unicode开放了吗?而且我没有提到新的文字类型
\"uHello \\u89ab thing\"u32
,我认为我理解这些。但: (便携式)源代码可以采用任何Unicode编码,例如UTF-8,UTF-16或任何(无论如何定义)代码页吗? 我可以在其中写
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格式(\“基本源字符集\”),然后用
\\uNNNN
表示法替换Unicode字符(或者编译器可以选择继续以Unicode表示法工作,因此必须确保它以相同的方式处理其他“ 6”。 你怎么看?     
已邀请:
新标准对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;
不:
long p\\u00F6rk;
但是,UCN也可用于其他目的。并非所有编译器都必须接受相同的源编码,但是现代编译器均支持某种编码方案,其中至少基本源字符具有相同的编码(即,现代编译器均支持某种ASCII兼容编码)。 UCN允许您仅使用基本字符编写源代码,而仍使用扩展名命名。例如,这在用源代码编写字符串文字\“°\”时将很有用,该源代码将同时编译为CP1252和UTF-8:
char const *degree_sign = \"\\u00b0\";
即使源编码不同,此字符串文字也会被编码为多个编译器上适当的执行编码,只要这些编译器至少为基本字符共享相同的编码即可。   (便携式)源代码可以采用任何Unicode编码,例如UTF-8,UTF-16或任何(无论如何定义)代码页吗? 该标准不是必需的,但是大多数编译器将接受UTF-8源。 Clang仅支持UTF-8源(尽管它与字符和字符串文字中的非UTF-8数据具有一定兼容性),gcc允许指定源编码并包括对UTF-8的支持,而VC ++会猜测该编码并可以猜测UTF-8。 (更新:VS2015现在提供了一个选项,可以强制将源字符集和执行字符集设置为UTF-8。)   我可以在myfu \\ u1234ntion中写上带有\\ u1234的标识符(出于任何目的) 是的,规范要求这样做,尽管正如我所说,并不是所有的编译器都可以实现此要求。   或者我可以使用Unicode定义的\“字符名称\”,如ICU中那样。
const auto x = \"German Braunb\\U{LOWERCASE LETTER A WITH DIARESIS}r.\"u32;
不,您不能使用Unicode长名称。   甚至在源代码本身的标识符中?那会是一种享受...咳嗽... 如果编译器支持包含所需扩展字符的源代码编码,则必须将在字面上直接写在源代码中的字符与等效的UCN完全相同。因此,是的,如果您使用支持C ++规范此要求的编译器,则可以直接在源代码中将任何字符写入其源字符集中,而不必担心编写UCN。     
我认为其目的是允许在标识符中使用Unicode字符,例如:
long pöjk;
ostream* å;
    
我建议使用
clang++
而不是
g++
。 Clang被设计为与GCC(维基百科源)高度兼容,因此您很可能可以替换该命令。 我想在源代码中使用希腊符号。 如果以代码可读性为目标,那么(例如)使用ѭ15而不是
alpha
是合理的。特别是在较大的数学公式中使用时,可以在源代码中更轻松地阅读它们。 为此,这是一个最小的工作示例:
> cat /tmp/test.cpp
#include <iostream>

int main()
{
    int α = 10;
    std::cout << \"α = \" << α << std::endl;
    return 0;
}
> clang++ /tmp/test.cpp -o /tmp/test
> /tmp/test 
α = 10
    
本文https://www.securecoding.cert.org/confluence/display/seccode/PRE30-C.+Do+not+create+a+universal+character+name+through+concatenation符合
int \\u0401;
兼容的想法代码,尽管它基于C99,而不是C ++ 0x。     
当前版本的gcc(到目前为止,最新版本为5.2)仅支持ASCII,在某些情况下还支持EBCDIC输入文件。因此,标识符中的Unicode字符必须使用ASCII编码文件中的\\ uXXXX和\\ UXXXXXXXX转义序列表示。虽然可以在EBCDIC编码的输入文件中将Unicode字符表示为?? / uXXXX和?? / UXXXXXXX,但我尚未对此进行测试。无论如何,只要安装了最新版本的iconv,一个简单的单行cpp修补程序就可以直接读取UTF-8输入。详细信息在 https://www.raspberrypi.org/forums/viewtopic.php?p=802657 并可能由补丁总结
diff -cNr gcc-5.2.0/libcpp/charset.c gcc-5.2.0-ejo/libcpp/charset.c
*** gcc-5.2.0/libcpp/charset.c  Mon Jan  5 04:33:28 2015
--- gcc-5.2.0-ejo/libcpp/charset.c  Wed Aug 12 14:34:23 2015
***************
*** 1711,1717 ****
    struct _cpp_strbuf to;
    unsigned char *buffer;

!   input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
    if (input_cset.func == convert_no_conversion)
      {
        to.text = input;
--- 1711,1717 ----
    struct _cpp_strbuf to;
    unsigned char *buffer;

!   input_cset = init_iconv_desc (pfile, \"C99\", input_charset);
    if (input_cset.func == convert_no_conversion)
      {
        to.text = input;
    

要回复问题请先登录注册