有什么理由分配-0?

Any reason to assign -0?

我正在使用 Lint 检查一些旧的 C 代码,偶然发现了这一行:

int16_t max = -0;

Lint 消息是 "Constant expression evaluates to 0 in operation '-'"。

有人会使用 -0 有什么原因吗?

在 C 规范 (6.2.6.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; 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 -(2N) (two’s complement);
  • the sign bit has the value -(2N - 1) (one’s 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 one’s complement), is a trap representation or a normal value. In the case of sign and magnitude and one’s complement, if this representation is a normal value it is called a negative zero.

也就是说,C支持三种不同的representations for signed integers and two of them have the concept of signed zero,区分了正零和负零

所以,我的解释是,您的代码片段的作者可能试图生成负零值。但是,正如中所指出的,这个表达式实际上不能产生负零,这意味着作者可能在那里做出了错误的假设。

不,我看不出有任何理由。其他人提到可以有 "negative zero" 的平台,但是这个表达式永远不会产生这样的负零,所以这是没有用的。

C标准中对应的段落是6.2.6.2 p3,重点是我的:

If the implementation supports negative zeros, they shall be generated only by:

— the &, |, ^, ~, <<, and >> operators with operands that produce such a value;

— the +, -, *, /, and % operators where one operand is a negative zero and the result is zero;

— compound assignment operators based on the above cases.

例如,要在这样的平台上生成负零,您可以使用 ~INT_MAX,但对于其他表示,这不会是零,因此代码不是很便携。

这是针对使用 CPU 和 one's complement 数字的架构。

  • 补码是一种表示负数的方式,具有 -0。仍在使用浮点数。
  • 对于无符号数,最大数确实是 -0:全 1。

我们习惯了补码,多了一个负数。虽然一个人的补码在零附近有一些麻烦,但同样适用于 MIN_INT 附近的二进制补码:-MIN_INT == MIN_INT.

上面的代码可能是无符号数:

uint16_t max = (uint16_t) -1;

C99 或更高版本没有理由。

int16_t 是精确宽度的整数类型。

The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits. C11dr §7.20.1.1 1

二进制补码中没有带符号的零。所以代码相当于

int16_t max = 0;

IMO,int16_t max = -0; 希望 的结果,在非 2 的补码平台上,是将 max 初始化为 -0 到标记长度为 0 或仅包含值为 -0.

的元素的数组