【问题标题】:Char conversion in gccgcc中的字符转换
【发布时间】:2020-05-14 18:30:36
【问题描述】:

什么是 char 隐式类型转换规则?以下代码给出了 -172 的尴尬输出。

char x = 200;
char y = 140;
printf("%d", x+y);

我的猜测是,被签名后,x 被转换为 72,y 被转换为 12,这应该给出 84 作为答案,但上面提到的情况并非如此。我在 Ubuntu 上使用 gcc。

【问题讨论】:

    标签: gcc casting char int


    【解决方案1】:

    以下代码给出了 -172 的尴尬输出。

    溢出的行为取决于实现,但显然在您的情况下(和我的情况)char 有 8 位,它的表示是 2 的补码。所以unsigned char 200 和 140 的二进制表示是11001000 和 10001100,对应于 signed char -56 和 -116 的二进制表示,-56 + -116 等于 -172(char 被提升为 int 以进行加法)。

    强制 xysigned 的示例,无论 char 的默认值如何:

    #include <stdio.h>
    
    int main()
    {
      signed char x = 200;
      signed char y = 140;
    
      printf("%d %d %d\n", x, y, x+y);
      return 0;
    }
    

    编译和执行:

    pi@raspberrypi:/tmp $ gcc -Wall c.c
    pi@raspberrypi:/tmp $ ./a.out
    -56 -116 -172
    pi@raspberrypi:/tmp $ 
    

    我的猜测是被签名后,x 被转换成 72,y 被转换成 12

    您认为高位已被删除(11001000 -> 1001000 和 10001100 -> 1100),但事实并非如此,这与 IEEE 浮点数使用位作为符号相反。

    【讨论】:

    • 在这种情况下没有未定义的行为,因为 200 (resp 140) 到 char 的转换中的溢出是实现定义的,而在 x+y 中,添加发生在 @987654335 之间@操作数根据cigix.me/c17#6.3.1.1.p2
    • @PascalCuoq 我不是在谈论加法,而是关于将 200 和 140 分配给具有 8 位的有符号字符的溢出
    • 正如我所说,这是实现定义的,而不是未定义的。 cigix.me/c17#6.5.16.1.p2 中的“转换”和 cigix.me/c17#6.3.1.3.p3 中的“结果是实现定义的或实现定义的信号被引发”
    • 是的,我用'undefined'说错了,我更正了,谢谢,我的英语很差^^
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2012-12-06
    • 1970-01-01
    相关资源
    最近更新 更多