将带符号的正整数输入为无符号整数(反之亦然)

Type punning a positive signed integer into an unsigned (and vice versa)

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?)不这样做,但它是否定义了?

简而言之,是的——标准保证对于共享的正值范围,无符号类型的值的按位表示与有符号类型的相同。

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

¶6 For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements. The type _Bool and the unsigned integer types that correspond to the standard signed integer types are the standard unsigned integer types. The unsigned integer types that correspond to the extended signed integer types are the extended unsigned integer types. The standard and extended unsigned integer types are collectively called unsigned integer types.40)

¶9 The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of the same value in each type is the same.41) A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

40) Therefore, any statement in this Standard about unsigned integer types also applies to the extended unsigned integer types.

41) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.

具体如dbush , section 6.2.6 Representation of types, and section 6.2.6.2 Integer types,还包含相关信息:

¶2 For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:

  • the corresponding value with sign bit 0 is negated (sign and magnitude);
  • the sign bit has the value -(2M) (two's complement);
  • the sign bit has the value -(2M- 1) (ones' complement).

Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones' complement), is a trap representation or a normal value. In the case of sign and magnitude and ones' complement, if this representation is a normal value it is called a negative zero.