B&R say in their book "The C Programming Language"- Enumerations provide a convenient way to associate constant values with names, an alternative to #define
with the advantage that the values can be generated for you.
So I defined enum constants for -1L, 1U and 1UL. The result is not what I expected, it should have been the same in both cases.
#include<stdio.h>
#define NEGATIVE_SIG_LONG -1L
#define UNSIG_INT 1U
#define UNSIG_LONG 1UL
main()
{
enum { ENUM_NEGATIVE_SIG_LONG = -1L, ENUM_UNSIG_INT = 1U, ENUM_UNSIG_LONG = 1UL};
printf("-1L < 1U: %d\n", -1L < 1U); // outputs: 1
printf("-1L > 1UL: %d\n\n", -1L > 1UL); // outputs: 1
printf("-1L < 1U: %d\n", NEGATIVE_SIG_LONG < UNSIG_INT); // outputs: 1
printf("-1L > 1UL: %d\n\n", NEGATIVE_SIG_LONG > UNSIG_LONG); // outputs: 1
printf("-1L < 1U: %d\n", ENUM_NEGATIVE_SIG_LONG < ENUM_UNSIG_INT); // outputs: 1
printf("-1L > 1UL: %d\n", ENUM_NEGATIVE_SIG_LONG > ENUM_UNSIG_LONG); // outputs: 0, expected 1
return 0;
}
In C enumeration constants have the type int
.
From the C Standard (6.4.4.3 Enumeration constants)
2 An identifier declared as an enumeration constant has type int
So in this call
printf("-1L < 1U: %d\n", ENUM_NEGATIVE_SIG_LONG < ENUM_UNSIG_INT); // outputs: 1
there is used the expression
-1 < 1
that yields to 1.
In this call
printf("-1L > 1UL: %d\n", ENUM_NEGATIVE_SIG_LONG > ENUM_UNSIG_LONG); // outputs: 0, expected 1
there is used the expression
-1 > 1
that yields 0
.
As for these calls
printf("-1L < 1U: %d\n", -1L < 1U); // outputs: 1
printf("-1L > 1UL: %d\n\n", -1L > 1UL); // outputs: 1
then it seems the type signed long can contain all values of the type unsigned int. So the expression
-1L < 1U
yields 1.
On the other hand, the type signed long
is unable to contain all values of the type unsigned long
. The common type will be unsigned long
. So the expression -1
L is converted to the type unsigned long
and yields the maximum value of this type that is greater than 1UL
.
Pay attention to that the function main shall have the return type int
.
int main( void )