宽字符的意外值

时间:2017-03-12 15:53:55

标签: c

鉴于此程序,它会打印-43632 1。预计第二个值为1,但我不明白它是如何计算负值的。

在ISO9899标准中,它解释了如何计算它?

#include <stdio.h>
int x = L'\uaaaa9', y = L'\uaaaa';

main()
{
  printf("%d %d\n", x-0xaaa9, y-0xaaa9);
}

编辑:编写这个荒谬的程序我试着理解什么时候有多个字符组成的常量字符是有效的,因为在标准中它允许使用该语言的语法(参见附录A以获得BNF的摘要)单个constant-char中的多个字符。

1 个答案:

答案 0 :(得分:1)

标准中的位置 - 无处可去。您的计划不符合严格要求:

% gcc test.c -Wall -Werror -pedantic -std=c11
test.c:2:9: error: character constant too long for its type [-Werror]
 int x = L'\uaaaa9', y = L'\uaaaa';

L'\uaaaa'是一个字符后跟另一个字符L'9'

C11 6.4.4.4p11说:

  

包含多个多字节字符或单个多字节字符的宽字符常量的值,该字符映射到扩展执行字符集的多个成员,或包含未在扩展执行字符集中表示的多字节字符或转义序列,是实现定义。

The behaviour of GCC in the case of integer character constants is

  

编译器一次评估一个字符的多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到宽度的新字符的位模式中一个目标角色。最终的位模式为int类型,因此无论单个字符是否有符号都是有符号的。如果常量中的字符数多于目标int中的符号,则编译器会发出警告,并忽略多余的前导字符。

然而,我越读标准,我感觉GCC正确记录了多字符宽字符常量的情况 not ,因为文档只是提到类型的字符常量int,但L''常量应生成值wchar_t

在任何情况下,您看到的值-43632都来自L'\uaaaa9'在您的平台上具有值L'9'的事实,即(wchar_t)0x39; )0x39 - 0xaaa9将导致-43632。

总而言之,从不依赖多字符宽常量产生任何合理的东西,因为标准不支持它。多字符整数常量也是可疑的,因为虽然它们可能很有用,但它们的值仍然是实现定义的,并非所有实现都可能同意。