'u0B95'是多字符文字吗?

Is 'u0B95' a multicharacter literal?

本文关键字:文字 字符 u0B95      更新时间:2023-10-16

在我之前的回答中,我对以下警告做出了回应,因为'u0B95'需要三个字节,因此是多字符文字

warning: multi-character character constant [-Wmultichar]

但实际上,我不认为我是对的,我也不认为gcc是对的。标准规定:

包含多个c-char的普通字符文字是多字符文字

c-char的一个生成规则是通用字符名(即uXXXXUXXXXXXXX)。由于u0B95是单个c-char,因此它不是多字符文字。但现在它变得一团糟。标准还说:

包含单个c-char的普通字符文字的类型为char,其值等于执行字符集中c-char编码的数值。

因此,我的文字具有类型char和执行字符集中的字符值(如果该字符集中不存在,则为实现定义的值)。char只被定义为足够大,可以存储基本字符集的任何成员(标准实际上没有定义,但我认为它意味着基本执行字符集):

声明为字符(char)的对象应足够大,以存储实现的基本字符集的任何成员。

因此,由于执行字符集是char可以保存的所有值的超集,因此我的字符可能不适合char

那么我的char有什么值呢?这似乎在任何地方都没有定义。标准确实规定,对于char16_t文字,如果该值不可表示,则程序格式不正确。不过,它并没有提到普通的文学作品。

那到底发生了什么?这只是标准上的混乱还是我遗漏了什么?

我认为如下:

如果字符文字的值超出了为char定义的实现定义范围(对于没有前缀的文字),则该值将被定义为实现(来自第2.14.3.4节)

如果'u0B95'不在为char定义的实现定义范围内(如果char为8位,则会如此),则其值将由实现定义,此时GCC可以使其值成为多个c-char的序列,从而成为多字符文字。

有人发布了一个答案,正确回答了我问题的第二部分(char的值是多少?),但后来删除了他们的帖子。既然那部分是正确的,我将在这里把它和我对第一部分的回答一起复制出来(它是多字符的文字吗?)。


'u0B95'不是多字符文字,gcc在这里是错误的。如问题所述,多字符文字由(§2.14.3/1)定义:

包含多个c-char的普通字符文字是多字符文字

由于通用字符名c-char的一个扩展,因此文字'u0B95'仅包含一个c-字符。如果普通文字不能包含通用字符名,则将u0B95视为六个独立的字符(u0等)是有意义的,但我在任何地方都找不到这种限制。因此,它是单个字符,而文字不是多字符文字。

为了进一步支持这一点,为什么会被认为是多个字符?在这一点上,我们甚至还没有给它一个编码,所以我们不知道它会占用多少字节。在UTF-16中需要2个字节,在UTF-8中需要3个字节,而在一些想象中的编码中只需要1个字节。

那么文字字符的值是多少呢?首先,通用字符名被映射到执行字符集中的相应编码,除非它没有映射,在这种情况下,它具有实现定义的编码(§2.14.3/5):

通用字符名被转换为所命名字符的适当执行字符集中的编码。如果没有这样的编码,则通用字符名将被转换为实现定义的编码。

无论哪种方式,char文字的值都等于编码的数值(§2.14.3/1):

包含单个c-char的普通字符文字的类型为char,其值等于执行字符集中c-char编码的数值。

现在是重要的部分,不便地隐藏在本节的另一段中。如果该值不能在char中表示,则获得实现定义的值(§2.14.3/4):

如果字符文字的值超出为char定义的实现定义范围(对于没有前缀的文字),则由实现定义。。。

根据规范,'u0B95'是一个字符类型的字符文字,其值等于执行字符集中的字符编码。您是对的,规范中没有说明由于单个字符无法表示该值而无法实现字符文字的情况。行为未定义。

有就这个问题向委员会提交的缺陷报告:例如。,http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#912

目前提出的解决方案似乎是指定这些字符文字也是int,并且具有实现定义的值(尽管所提出的语言不太适合这一点),就像多字符文字一样。我不喜欢这种解决方案,我认为更好的解决方案是说这样的文字格式不正确。

这是clang中实现的内容:http://coliru.stacked-crooked.com/a/952ce7775dcf7472

因为没有字符编码前缀,gcc(和任何其他符合要求的编译器)将看到'u0B95',并认为1)字符类型和2)多字符,因为字符串中有多个字符代码。

  • u'u0B95'是一个UTF16字符
  • u'u0B95u0B97'是一个多字符的UTF16字符
  • CCD_ 33是一个UTF32字符

等。