【问题标题】:Assign char16_t with character literal codepoints outside of basic multilingual plane用基本多语言平面之外的字符文字代码点分配 char16_t
【发布时间】:2014-09-05 20:01:53
【问题描述】:

在我今天早些时候观看的关于 Unicode 的一次演讲中,当您尝试分配一个太长而无法由 char16_t 类型表示的字符文字时,会发生什么情况有些混乱。演示者说,根据对标准的阅读,该程序应该是格式错误的,但 gcc 无论如何都会接受它。他没有澄清,Youtube 也不允许我提问。

我自己的测试确认以下代码被g++-4.8和g++-4.9接受。 (带有警告。)

int main() {
  char16_t a = u'\U0001F378';
}

http://coliru.stacked-crooked.com/a/6cb2206660407a8d
https://eval.in/188979

另一方面,clang 3.4 会产生错误。

哪个编译器是正确的?我找不到这方面的章节。

另外一个小问题,字符文字部分 §2.14.3 没有在 W 语法或部分正文中提及 \u\U 转义序列。这是疏忽吗?

【问题讨论】:

    标签: c++ unicode language-lawyer utf-16 string-literals


    【解决方案1】:

    程序格式错误,应该无法编译。

    2.14.3/2 以字母 u 开头的字符文字,例如 u'y',是 char16_t 类型的字符文字。这 包含单个 c-char 的 char16_t 文字的值等于其 ISO 10646 代码点值,前提是 代码点可以用单个 16 位代码单元表示。 (也就是说,只要它是基本的多语言 平面代码点。)如果该值在 16 位内无法表示,则程序格式错误...

    强调我的。

    \u\U 不是 2.14.3 含义内的转义序列。它们是通用字符名称,在 2.3/2 中进行了描述。它们不仅限于字符和字符串字面量,还可能出现anywhere in the program:

    int main() {
        int \u0410 = 42;
        return \u0410;
    }
    

    \u0410A,又名西里尔大写字母 A。

    【讨论】:

    • 我不敢相信我在正确的部分并且完全错过了它。 :/ 谢谢。而且,通用字符名称,我想它们是必需的,但是伙计,为 C++ 制作一个合适的 IDE 变得更具挑战性。我假设翻译是在像三元组一样的标记化过程中完成的,这会产生有趣的混淆代码机会。
    • 翻译阶段,包括处理三元组和通用字符名称的细节,在 2.2/1 中有描述
    猜你喜欢
    • 2018-01-22
    • 2011-05-01
    • 2011-12-13
    • 2012-04-03
    • 2013-10-23
    • 1970-01-01
    • 2020-05-23
    • 2018-02-03
    相关资源
    最近更新 更多