无符号和更大的符号类型之间的隐式转换不一致的行为 [英] Inconsistent behaviour of implicit conversion between unsigned and bigger signed types

查看:172
本文介绍了无符号和更大的符号类型之间的隐式转换不一致的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的例子:

 的#include<&stdio.h中GT;INT主要(无效)
{
    unsigned char型一= 15; / *一个字节* /
    无符号短B = 15; / *两个字节* /
    unsigned int类型C = 15; / *四个字节* /    长×= -a; / *八个字节* /
    的printf(%LD \\ N,X);    X = -b;
    的printf(%LD \\ N,X);    X = -c;
    的printf(%LD \\ N,X);    返回0;
}

要编译我使用GCC 4.4.7(和它没有给我警告):

  gcc的-g -std = C99 -pedantic-错误-Wall -W check.c

我的结果是:

  -15
-15
4294967281

问题是,为什么这两个 unsigned char型无符号短值是传播正确地(签字),而 unsigned int类型是不是?是否有任何引用或规则上呢?

下面是从 GDB 的结果(词在little-endian顺序)相应的:

 (GDB)x / 2W和放大器; X
0x7fffffffe168:11111111111111111111111111110001 11111111111111111111111111111111(GDB)x / 2W和放大器; X
0x7fffffffe168:11111111111111111111111111110001 00000000000000000000000000000000


解决方案

这是由于如何应用到操作数和一元减法的结果有相同的类型要求的整数促销。这是覆盖在部分 6.5.3.3 单目算术运算符的和说(的重点煤矿前进的):


  

一元的结果 - 运算符是它的(推动)操作数的负值。 整数促销活动上进行操作,结果具有推广型


和它覆盖在C99标准草案部分整型提升 6.3 转换的说:


  

如果int可以重新present原始类型的所有值,该值被转换为int;否则,将其转换为一个unsigned int。这些被称为整数促销。 48)所有其它类型在整数提升不会改变。


在在前两种情况下,推广将是的 INT 的,其结果将是的 INT 的。在的情况下的 的要求unsigned int类型没有任何推广,但结果将需要转换回的 unsigned int类型

-15 被转换成的 unsigned int类型的使用列明有关规则 6.3.1.3 符号和无符号整数的它说:


  

否则,如果新类型是无符号的值被重复地增加或减1比可以重新$ P $在新型psented直到该值是在新的类型的范围的最大值更转换 49)


因此​​,我们最终与 -15 +(UMAX + 1)这将导致 UMAX - 14 这将导致在一个大的无符号值。这就是为什么有时候你会看到code使用 1 转换为一个无符号的值,以获得一个类型,因为它总是会最终成为的最大无符号值 -1 + UMAX + 1 UMAX

Consider following example:

#include <stdio.h>

int main(void)
{
    unsigned char a  = 15; /* one byte */
    unsigned short b = 15; /* two bytes */
    unsigned int c   = 15; /* four bytes */

    long x = -a; /* eight bytes */
    printf("%ld\n", x);

    x = -b;
    printf("%ld\n", x);

    x = -c;
    printf("%ld\n", x);

    return 0;
}

To compile I am using GCC 4.4.7 (and it gave me no warnings):

gcc -g -std=c99 -pedantic-errors -Wall -W check.c

My result is:

-15
-15
4294967281

The question is why both unsigned char and unsigned short values are "propagated" correctly to (signed) long, while unsigned int is not ? Is there any reference or rule on this ?

Here are results from gdb (words are in little-endian order) accordingly:

(gdb) x/2w &x
0x7fffffffe168: 11111111111111111111111111110001    11111111111111111111111111111111 

(gdb) x/2w &x
0x7fffffffe168: 11111111111111111111111111110001    00000000000000000000000000000000

解决方案

This is due to how the integer promotions applied to the operand and the requirement that the result of unary minus have the same type. This is covered in section 6.5.3.3 Unary arithmetic operators and says (emphasis mine going forward):

The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.

and integer promotion which is covered in the draft c99 standard section 6.3 Conversions and says:

if an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions.

In the first two cases, the promotion will be to int and the result will be int. In the case of unsigned int no promotion is required but the result will require a conversion back to unsigned int.

The -15 is converted to unsigned int using the rules set out in section 6.3.1.3 Signed and unsigned integers which says:

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.49)

So we end up with -15 + (UMAX + 1) which results in UMAX - 14 which results in a large unsigned value. This is sometimes why you will see code use -1 converted to to an unsigned value to obtain the max unsigned value of a type since it will always end up being -1 + UMAX + 1 which is UMAX.

这篇关于无符号和更大的符号类型之间的隐式转换不一致的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆