将正负号整数转换为无符号(反之亦然)

时间:2019-03-17 16:50:21

标签: c language-lawyer unsigned signed type-punning

union   Positive_Small {
    int8_t  s;
    uint8_t u;
};

union Positive_Small    x = {.s = 3};
union Positive_Small    y = {.u = 4};

assert(x.u == 3);
assert(y.s == 4);

这是定义的行为吗? 标准是否保证有符号整数类型的正范围与无符号整数类型的正范围具有相同的表示形式?

我想象没有一种疯狂的实现方式(也许是DS9K?),但是没有定义吗?

1 个答案:

答案 0 :(得分:4)

简洁地说,是的-该标准保证对于共享的正值范围,无符号类型的值的按位表示与带符号类型的相同。

C11 Section 6.2.5 Types定义了这一点(以及许多其他术语和行为):

  

¶6对于每种有符号整数类型,都有一个对应的(但不同的)无符号整数类型(用关键字unsigned指定)使用相同的存储量(包括符号信息)并且具有相同的对齐要求。类型_Bool和与标准有符号整数类型相对应的无符号整数类型是标准无符号整数类型。与扩展的有符号整数类型相对应的无符号整数类型是扩展的无符号整数类型。标准和扩展的无符号整数类型统称为无符号整数类型 40)

     

¶9有符号整数类型的非负值范围是对应的无符号整数类型的子范围,并且每种类型中相同值的表示形式都相同。 41)计算涉及无符号操作数的对象永远不会溢出,因为不能用所得的无符号整数类型表示的结果的模数要比该所得类型可以表示的最大值大一模。

     

40)因此,本标准中有关无符号整数类型的任何声明也适用于扩展的无符号整数类型。

     

41)相同的表示形式和对齐要求旨在隐含作为函数参数,函数返回值和并集成员的互换性。

具体来说,dbush pointed outsection 6.2.6 Representation of typessection 6.2.6.2 Integer types还包含相关信息:

  

¶2对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位。不需要任何填充位; signed char不得有任何填充位。恰好有一个符号位。作为值位的每个位应具有与相应无符号类型的对象表示形式中的相同位相同的值(如果有符号类型的 M 个值位和 N 为无符号类型,然后 M≤N )。如果符号位为零,则它将不影响结果值。如果符号位为1,则应通过以下方式之一修改值:

     
      
  • 取反符号位0的对应值(符号和幅度);
  •   
  • 符号位的值为-(2 M )(二进制补码);
  •   
  • 符号位的值为-(2 M -1)(一个人的补语)。
  •   
     

其中哪些适用于实现定义,是否具有符号位1和所有值位均为零(对于前两个)或具有符号位和所有值位1(等于1的补码)的值是实现定义的?陷阱表示形式或正常值。对于正负号和幅度以及“ 1”的补码,如果该表示形式是正常值,则称为“ 负零”。