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/34526432/

相关文章:

c++ - ASIO signal_set对多个IO线程不可靠,取决于代码顺序?

c++ - 为什么thread_local不能应用于非静态数据成员以及如何实现线程局部非静态数据成员?

c++ - std::getline() 在使用 cout 时返回内存地址

python - 在孟加拉语单词中查找音节的正则表达式

c++ - 在使用宽字符串解析罗马数字时,Boost spirit 库无法正常工作

python - 如何在 Python 中连接和输出 unicode 文本变量

c - C 枚举中的最后一个逗号是必需的吗?

php - 如何使用 CodeIgniter 在 SQL Server 数据库中存储多字节字符

javascript - "function x.y () {...}"出现语法错误?

C# Regex 用字符串末尾的多个捕获和匹配替换奇怪的行为?