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

标签 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

带有附加文本

An identifier is an arbitrarily long sequence of letters and digits. Each universal-character-name in an identifier shall designate a character whose encoding in ISO 10646 falls into one of the ranges specified in E.1. [...]



我不能完全理解这意味着什么。从旧的标准我习惯了写“通用字符名称”\u89ab例如。但是在标识符中使用那些......?真的吗?

新标准是否对 Unicode 更加开放? 而且我没有提到新的文字类型 "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 阶段:

    Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set [...] if necessary. The set of physical source file characters accepted is implementation-defined. [...] Any source file character not in the basic source character set (2.3) is replaced by the universal-character-name that designates that character. (An implementation may use any internal encoding, so long as an actual extended character encountered in the source file, and the same extended character expressed in the source file as a universal-character-name (i.e., using the \uXXXX notation), are handled equivalently except where this replacement is reverted in a raw string literal.)



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

    你怎么认为?

    最佳答案

    Is the new standard more open w.r.t to Unicode?


    关于允许在标识符中使用通用字符名称,答案是否定的;在 C99 和 C++98 中,标识符中允许使用 UCN。然而,编译器直到最近才实现该特定要求。我认为 Clang 3.3 引入了对此的支持,并且 GCC 已经为此提供了一段时间的实验性功能。 Herb Sutter 在他的 Build 2013 演讲“C++ 的 future ”中还提到,这个特性也将在某个时候出现在 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";
    
    这个字符串文字在多个编译器上被编码为适当的执行编码,即使源编码不同,只要编译器至少共享基本字符的相同编码。

    Can (portable) source code be in any unicode encoding, like UTF-8, UTF-16 or any (how-ever-defined) codepage?


    标准不要求它,但大多数编译器会接受 UTF-8 源。 Clang 只支持 UTF-8 源代码(虽然它对字符和字符串文字中的非 UTF-8 数据有一定的兼容性),gcc 允许指定源编码并包括对 UTF-8 的支持,VC++ 会猜测编码并且可以猜测UTF-8。
    (更新:VS2015 现在提供了 option 来强制源和执行字符集为 UTF-8。)

    Can I write an identifier with \u1234 in it myfu\u1234ntion (for whatever purpose)


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

    Or can i use the "character names" that unicode defines like in the ICU, i.e.

    const auto x = "German Braunb\U{LOWERCASE LETTER A WITH DIARESIS}r."u32;
    

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

    or even in an identifier in the source itself? That would be a treat... cough...


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

    关于C++11 中的 Unicode 标识符和源代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5676978/

    相关文章:

    javascript - IMACROS 将 iim 代码转换为 javascript 后出现代码错误

    c++ - 如何在 Windows 中用 c/c++ 将 double 类型写入文件?

    c++ - 是否可以按照 C++11 标准使用静态成员函数作为 C 回调?

    函数内的 Python 2.7 Unicode 错误(使用 __future__ print_function 和 unicode_literals)

    swift - 查找字节的 UTF8 字符(以十六进制表示)

    python - "SyntaxError: Non-ASCII character ..."或 "SyntaxError: Non-UTF-8 code starting with ..."尝试在 Python 脚本中使用非 ASCII 文本

    c++ - 使用 Boost 构建单元测试时出现链接器错误

    python - 在 Python 2 + GTK 中检测/删除未配对的代理字符

    c# - 如何在 C# 的 getter 和 setter 方法中进行验证?

    c++ - 我正在使用可变参数模板在 C++11 中创建一个元组类。我如何使用它的实例变量?