What is (INT32_MIN + 1) when int32_t is an extende

2020-08-26 11:19发布

问题:

Imagine this situation. int32_t is an extended integer type and it's represented in two's complement (as the standard required int32_t to be represented). This means that INT32_MIN is -2147483648 (0x80000000).

Meanwhile int is a standard integer type and it's represented in one's complement (as the standard allows). This means that INT_MIN is -2147483647.

Now correct me if I'm wrong, but I think both types have the same width, which means, according to 6.3.1.1.1 (emphasis mine):

The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.

So the rank of int32_t is lower than that of int.

Now 6.3.1.8 (usual arithmetic conversions) says (emphasis mine):

<...> Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands: If both operands have the same type, then no further conversion is needed. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.

So if understand it correctly, in this code block:

int32_t x = INT32_MIN;
int y = 1;
x + y; // What happens here?

In the expression x + y, x has to be promoted to int, and INT32_MIN is outside of the range of int.

Is this a bug in the standard or am I missing something?

In other words, what does the expression x + y in this context evaluate to, as defined by the standard?

回答1:

int32_t is optional. A conforming implementation cannot have 32-bit one's complement int and 32-bit two's complement extended integer type int32_t; if int is one's complement, int32_t would most likely not be provided.

Here's one reason 32-bit one's complement int and 32-bit two's complement extended integer type int32_t can't coexist. Quoting the N1570 draft:

7.20.2 Limits of specified-width integer types

1 The following object-like macros specify the minimum and maximum limits of the types declared in <stdint.h>. Each macro name corresponds to a similar type name in 7.20.1.

2 Each instance of any defined macro shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Its implementation-defined value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below, with the same sign, except where stated to be exactly the given value.

...

INTN_MIN                                  exactly -(2N-1)

In the situation you describe, INT32_MIN must have value exactly -2^31, but due to the integer promotions, it must have a type that cannot hold that value. This contradiction prevents providing int32_t at all.



回答2:

Meanwhile int is a standard integer type and it's represented in one's complement

Extended integers are implementation defined and only have to be binary numbers, and signed integers are required to be represented in one’s complement, two’s complement, or sign and magnitude notation

intxx_t is a fixed size int type it has to have the same representation as int. Because intxx_t is two's complement it requires int to be the same.