在C ++代码中使用“变音符号”

时间:2011-04-12 14:20:11

标签: c++ compiler-construction

  

可能重复:
  C++ source in unicode

我刚在项目中发现了这行代码:

string überwachung;

我很惊讶,因为实际上我认为你不允许在C ++代码中使用变音符号<äöü'而不是字符串等等,这会导致编译错误。但是这与Visual Studio 2008编译得很好。

  • 这是一个特殊的微软功能,还是其他编译器也允许使用变音符号?
  • 是否存在任何潜在问题(可移植性,系统语言设置......)?
  • 我清楚地记得这是不允许的。什么时候改变了?

亲切的问候任何澄清

P.S。:工具cppcheck甚至会将此用法标记为错误,即使它编译

5 个答案:

答案 0 :(得分:6)

海湾合作委员会抱怨: codepad

  

:错误:在程序中错误'\ 303'

C ++语言标准本身将基本源字符集限制为91个可打印字符加上制表符,换页符和换行符,这些都在ASCII中。但是,有一个很好的脚注:

  

基本源字符集成员的字形旨在识别子集中的字符   ISO / IEC 10646,对应于ASCII字符集。但是,因为从源文件字符映射到   源字符集(在翻译阶段1中描述)被指定为实现定义,需要实现   记录源文件中基本源字符的表示方式。

..翻译阶段1是(强调我的)

  

物理源文件字符以实现定义的方式映射到基本源   字符集(如果需要,引入行尾指标的换行符)。 一套物理   接受的源文件字符是实现定义的。

通常,您不应在代码中使用变音符号或其他特殊字符。如果可行,但如果可行,则它是特定于编译器的功能。

答案 1 :(得分:4)

参见C ++ 03标准的E / 2节:

  

1此子句列出了在C ++标识符(2.10)中的通用字符名称中有效的完整十六进制代码值。

     

...

     

拉丁语:00c0-00d6,00d8-00f6,00f8-01f5,01fa-0217,0250-02a8,1e00-1e9a,1ea0-1ef9

这包括大多数重音字母。

问题是C ++ 03没有指定UTF-8作为输入格式。甚至C ++ 11也保持与EBCDIC的兼容性。

所以,你当然可以用变音符号创建一个标识符;问题是得到一个文本编辑器,它将解释通用字符名称并正确显示它。否则,您将难以直接以十六进制格式\uXXXX输入Unicode,例如\u00FC的{​​{1}}。

在字符串常量中接受UTF-8而在标识符中不接受UTF-8的编译器会受到短视实现的影响。至少,Clang在阶段1中正确地将UTF-8翻译成通用字符名称。

答案 2 :(得分:3)

我相信这是适用的条款......

2.2字符集

  

基本源字符集   由96个字符组成:空格   字符,控制字符   代表水平标签,垂直   选项卡,换页和换行,再加上   以下91个图形字符:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ˆ & | ˜ ! = , \ " ’

因此,unlaut的使用似乎是特定于编译器的扩展。

答案 3 :(得分:1)

当且仅当您的编辑从具有变音符号(或其他变音符号)的字符转换为允许的字符之一时,标准才允许这样做。特别是,C ++中的标识符定义为:

identifier:
    nondigit
    identifier nondigit
    identifier digit

nondigit: one of
    universal-character-name
    _ a b c d e f g h i j k l m
      n o p q r s t u v w x y z
      A B C D E F G H I J K L M
      N O P Q R S T U V W X Y Z

据我所知,这不允许带有变音符号的字符(除了作为UCN)。在我看来,编译器需要为包含除上述字符之外的任何字符的程序发出至少一个诊断程序(尽管仍允许它翻译程序)。快速检查一下,我找不到一个能让VC ++为这段代码发出诊断的编译器标志。至少IMO,它在这方面不符合。

另一方面,这可以被视为VC ++实现C ++ 11的一个新功能。至少从N3242开始,新的C ++草案在上表后添加了一个新项:“其他实现定义的字符”。这使编译器可以接受它想要的任何其他字符(虽然它应该记录它们是什么)。

答案 4 :(得分:1)

编译器可以自由支持所需标识符中的任何字符。您的编译器显然支持变音符号。但是,语言标准无法保证。如果您希望您的程序符合标准,则不能使用变音符号。

另一个例子,一些编译器允许在标识符中使用$字符,而语言规范不支持它。