Reputation: 831
I am a student, going through the book by Kerningham and Ritchie for C.
A line in the book says that -1l
is less than 1u
because in that case unsigned int
is promoted to signed long
. But -1l > 1ul
because in this case -1l
is promoted to unsigned long
.
I can't really understand the promotion properly. What will be the value of -1l
when it is promoted to unsigned long? It'll be great if anyone can help.
Thanks.
Upvotes: 4
Views: 419
Reputation: 76785
In -1l > 1ul
the -1l
is promoted to unsigned long
, and by definition and Standard, -1 cast to an unsigned
type will be the largets value representable by that unsigned
type.
I got my inspiration from memory of this answer here to a quite relevant question.
And after looking at the C99 draft I have lingering around, see for example 6.3.1.3(2), where it says the maximum value representable by the type will be added or subtracted from the original value until it fits in the new type. I must warn you that char
, although it is an integer type, is treated special: it is implementation defined if char
is signed or unsigned. But that is, strictly, beside the question at hand.
Upvotes: 2
Reputation: 43748
This is actually a conversion. Promotions go from types with less rank than an integer to integer.
The rules for integer conversions in C are somewhat complex. They are, as per ISO C99 §6.3.1.8 ¶1:
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.
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
I'll try to explain them:
Try to convert to the larger type. When there is conflict between signed
and unsigned
, if the larger (including the case where the two types have the same rank) type is unsigned
, go with unsigned
. Otherwise, go with signed
only in the case it can represent all the values of both types.
Upvotes: 1
Reputation: 4070
When you're learning C, if you have a question, just write yourself a simple program:
#include <stdio.h>
main() {
int si = -1;
unsigned int ui = 1;
if ( si > ui ) printf("-1l > 1u\n");
else printf("-1l <= 1u\n");
}
You'll see that -1l > 1u
is shown for the output.
Because both si
and ui
have the same rank (they're both int
s), the rule says that the negative value will be promoted to unsigned at set to UINT_MAX
which is the largest possible unsigned value.
Upvotes: 0
Reputation: 215115
Implicit promotions are one of the most difficult things in the C language. If you have a C code expression looking like
if(-1l > 1ul)
then no "integer promotions" take place. Both types are of the same size, but different signedness. -1l will then be converted to unsigned long with a very large value. This is one of the rules in the "usual arithmetic conversions".
Upvotes: 1