问题
I found a few questions on this particular topic, but they were about C++.
How portable is casting -1 to an unsigned type?
converting -1 to unsigned types
Is it safe to assign -1 to an unsigned int to get the max value?
And when reading the answers, it seemed likely or at least not unlikely that this is one of those things where C and C++ differs.
The question is simple:
If I declare a variable with unsigned char/short/int/long var
or use any other unsigned types like fixed width, minimum width etc, is it then guaranteed that var = -1
will set var
to the maximum value it can hold? Is this program guaranteed to print "Yes"?
#include <stdio.h>
#include <limits.h>
int main(void) {
unsigned long var = -1;
printf("%s\n", var == ULONG_MAX ? "Yes" : "No");
}
回答1:
Is it guaranteed that assigning -1 to an unsigned type yields the maximum value?
Yes.
Is this program guaranteed to print "Yes"?
Yes.
It's a conversion, from int
-1
to unsigned long
. -1
can't be represented as unsigned long
. From C11 6.3.1.3p2:
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type
so we add one (ULONG_MAX + 1)
to -1
and we get -1 + (ULONG_MAX + 1) = ULONG_MAX
which is in range of unsigned long
.
回答2:
The conversion from -1
(signed int
) to a large unsigned type is well-defined, as per C17 6.3.1.3.
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type60).
This comes with a helpful foot note 60)
- The rules describe arithmetic on the mathematical value, not the value of a given type of expression.
So given unsigned long var = -1;
, the value becomes
-1
then adding one more than maximum value of unsigned long- Meaning
-1
+ULONG_MAX+1
=U_LONG_MAX
.
This is well-defined and portable behavior. Unlike conversions from unsigned to signed, that can invoke implementation-defined behavior.
Also, this is regardless of signedness format, since the mathematical value should be used, not the raw binary one. Had you done something like unsigned long var = (signed long)0xFFFFFFFFF;
then that would be another story in case of exotic/fictional systems with 1's complement or signed magnitude.
来源:https://stackoverflow.com/questions/65934534/is-it-guaranteed-that-assigning-1-to-an-unsigned-type-yields-the-maximum-value