代码之家  ›  专栏  ›  技术社区  ›  NeonMan

整数提升如何在C Cast上工作?

  •  3
  • NeonMan  · 技术社区  · 6 年前

    在编译器中,提升是否发生在显式强制转换之前是一致的?

    让我解释一下。有符号8位变量的,如

    int8_t s8a = -128; //<-- 0x80

    uint16_t s16b = s8a + 1; 我希望提升到一个更大的整数 0xFF81 然后分配,这是一个常见的灾难,并考虑在文件,如米斯拉C。但是以如下方式显式转换为无符号类型 uint16_t s16b = (uint16_t)s8a 我早就料到了 s8a 立即失去它的“符号性”,然后零扩展到16位 0x0080 但事实上恰恰相反,当它被符号扩展时 然后 0xFF80

    这是C的行为标准还是另一个未定义的行为?

    2 回复  |  直到 6 年前
        1
  •  5
  •   Eugene Sh.    6 年前

    这与整数提升无关,而是与类型转换有关。在您的案例中,流程由 C11 Standard - 6.3.1.3 Signed and unsigned integers (p2) :

    .. 如果新类型是无符号的,则该值将由 在新类型中表示,直到值在新类型的范围内

    所以在这里 0xFF80 = 0xFFFF + (-128) + 1 ,作为 0xFFFF 是可以在中表示的最大值 uint16_t

        2
  •  1
  •   Ian Abbott    6 年前

    给定初始化 int8_t s8a = -128;

    1. uint16_t s16b = s8a + 1; :
      1. 在表达式中 s8a + 1 ,中的值 s8a ( (int8_t)-128 )被提升为 (int)-128 (int)1 给予 (int)-127 .
      2. 在初始化中 uint16_t s16b = (int)-127; ,的 (内景)-127 已转换为 (uint16_t)0xff81 储存在 s16b .
    2. 在初始化的情况下 uint16_t s16b = (uint16_t)s8a + 1; :
      1. (uint16_t)s8a ,中的值 ( (国际)128 )已转换为 (uint16_t)0xff80 .
      2. 在表达式中 (uint16_t)0xff80 + 1 :
        • INT_MAX >= 65535 ,那么 (uint16)0xff80 (int)0xff80 加上 给予 (int)0xff81
        • 如果 INT_MAX < 65535 1 已转换为 (uint16_t)1 加上 (uint16)0xff80 给予 (uint16)0xff81
      3. 在初始化中 uint16_t s16b = (int)0xff81; (何时 整数最大值>=65535 ),或初始化 uint16_t s16b = (uint16_t)0xff81; (何时 内部最大值<65535
        • 如果 整数最大值>=65535 ,那么 (内景)0xff81 已转换为 (uint16)0xff81 储存在 s16b级 .
        • ,那么 (uint16)0xff81 .

    在这两种情况下 s16b级 .