Reputation: 469
I am going through some old C code using Lint which stumbled upon this line:
int16_t max = -0;
The Lint message is that the "Constant expression evaluates to 0 in operation '-'".
Is there any reason why someone would use -0?
Upvotes: 5
Views: 478
Reputation: 154280
No reason for it with C99 or later.
int16_t
is an exact-width integer type.
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
There is no signed zero with two’s complement. So code is equivalent to
int16_t max = 0;
IMO, the int16_t max = -0;
hoped for result, on a non-2's complement platform, was to initialize max
to -0
to flag an array of length 0 or one that only contained elements with the value -0
.
Upvotes: 0
Reputation: 109597
That is for an architecture using a CPU with one's complement numbers.
-0
: all 1s.We are accustomed to two's complement numbers, having one negative number more. Though one's complement has some troubles around zero, the same holds for two's complement around MIN_INT: -MIN_INT == MIN_INT
.
In the code above probably intended was unsigned numbers:
uint16_t max = (uint16_t) -1;
Upvotes: 0
Reputation: 29223
In the C specification (6.2.6.2 Integer types), it states the following (emphasis mine):
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.
In other words, C supports three different representations for signed integers and two of them have the concept of signed zero, which makes a distinction between a positive and a negative zero.
So, my explanation is that perhaps the author of your code snippet was trying to produce a negative zero value. But, as pointed out in Jens Gustedt's answer, this expression cannot actually produce a negative zero, which means the author may have made a wrong assumption there.
Upvotes: 7
Reputation: 78943
No, I can't see any reason for this. Others have mentioned that it is possible to have platforms with "negative zero", but such a negative zero can never be produced by this expression, so this is useless.
The corresponding paragraph in the C standard is 6.2.6.2 p3, emphasis is mine:
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.
To produce a negative zero on such a platform you could use ~INT_MAX
, for example, but that would not be a zero for other representations, so the code wouldn't be very portable.
Upvotes: 4