在 C++ 代码中使用“变音符号”[重复]

问题描述 投票:0回答:5

可能重复:
unicode 中的 C++ 源代码

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

string überwachung;

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

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

如有任何澄清,敬请谅解

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

c++ unicode
5个回答
6
投票

GCC对此抱怨: 键盘

:错误:程序中出现杂散“�”

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

基本源字符集成员的字形旨在识别来自以下子集的字符 ISO/IEC 10646 对应于 ASCII 字符集。然而,因为 从源文件字符到 源字符集(在翻译阶段 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 的兼容性。

因此,您当然可以创建一个带有变音符号的标识符;问题是获得一个文本编辑器来解释通用字符名称并正确显示它。否则,您将无法直接以十六进制格式输入 Unicode

\uXXXX
,例如
\u00FC
ü

在字符串常量中接受 UTF-8 但在标识符中不接受 UTF-8 的编译器会遭受短视的实现。 Clang 至少在第 1 阶段正确地将 UTF-8 转换为通用字符名称。


2
投票

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

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 的使用似乎是特定于编译器的扩展。


1
投票

编译器可以自由地支持它想要的标识符中的任何字符。您的编译器显然支持变音符号。但是,语言标准并不能保证这一点。如果您希望您的程序符合标准,则不能使用变音符号。

再比如,一些编译器允许在标识符中使用

$
字符,而语言规范不支持。


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++ 对此代码发出诊断的编译器标志。至少在我看来,它在这方面不符合要求。

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

© www.soinside.com 2019 - 2024. All rights reserved.