我正在使用Lint查看一些旧的C代码,后者偶然发现了这一行:
int16_t max = -0;
Lint消息是"常量表达式在操作中评估为0' - '"。
为什么有人会使用-0?
答案 0 :(得分:7)
在C规范(6.2.6.2整数类型)中,它声明了以下内容(强调我的):
对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位。不需要任何填充位;应该只有一个符号位。作为值位的每个位应具有与相应无符号类型的对象表示中的相同位相同的值(如果有 有符号类型中的M值位和无符号类型中的N,则为M£N)。如果符号位为零,则不应影响结果值。 如果符号位为1,则应通过以下方式之一修改该值:
- 符号位0的相应值被否定(符号和 大小);
- 符号位的值为 - (2N)(二的补码);
- 符号位的值为 - (2N - 1)(一个补码)。
其中哪一个适用于实现定义,以及是否 符号位为1且所有值位为零(前两位)的值,或 符号位和所有值位1(对于一个补码),是一个陷阱 表示或正常值。 在符号和数量的情况下 和一个补码,如果这个表示是正常值 称为负零。
换句话说,C支持三个不同的representations for signed integers,其中两个具有signed zero的概念,它区分了正零和负零。
所以,我的解释是,你的代码片段的作者可能试图产生负零值。但是,正如Jens Gustedt's answer所指出的,这个表达式实际上不会产生负零,这意味着作者可能在那里做出了错误的假设。
答案 1 :(得分:4)
不,我看不出任何理由。其他人已经提到过,有可能让平台有"负零",但是这个表达式永远不会产生这样的负零,所以这是没用的。
C标准中的相应段落是6.2.6.2 p3,重点是我的:
如果实现支持负零,则应生成它们 只有:
- &,|,^,〜,<<<>>具有操作数的运算符 产生这样的价值;
- +, - ,*,/和%运算符其中一个操作数为负零,结果为零;
- 化合物 基于上述情况的赋值算子。
要在这样的平台上产生负零,您可以使用~INT_MAX
,但是对于其他表示不会为零,因此代码不会非常便携。
答案 2 :(得分:0)
这适用于使用带one's complement个数字的CPU的架构。
-0
:全1。我们习惯于两个补码,一个负数更多。虽然一个补码在零附近有一些麻烦,但同样适用于MIN_INT周围的两个补码:-MIN_INT == MIN_INT
。
在上面的代码中,可能是无符号数字:
uint16_t max = (uint16_t) -1;
答案 3 :(得分:0)
没有理由使用C99或更高版本。
int16_t
是精确宽度整数类型。
typedef名称
intN_t
指定一个有符号整数类型,其宽度为N,没有填充位,以及二进制补码表示。因此,int8_t
表示这样的带符号整数类型,其宽度恰好为8位。 C11dr§7.20.1.11
没有带有二进制补码的零符号。所以代码相当于
int16_t max = 0;
在非2的补充平台上,IMO,int16_t max = -0;
希望获得结果,是将max
初始化为-0
以标记长度数组0或仅包含值为-0
的元素。