/*---------------------------------------------------------------------------*/ /* This test case provides empirical evidence that the compiler treats */ /* unsuffixed hexadecimal integer constants with values larger than LONG_MAX */ /* and no larger than ULONG_MAX as having "unsigned long" type. This is as */ /* required by the C standard, in all versions. */ /* */ /* "Integer Constants" C89: 3.1.3.2, C90: 6.1.3.2, C99: 6.4.4.1 */ /*---------------------------------------------------------------------------*/ #include #include /* Okay, how do we empirically test the type of an integer constant? A couple of tricks and tricky bits here: 1. Only signed types can hold values less than 0. 2. We will set up an expression such that the only term whose sign is in question is the integer constant. Iff it is signed, the result of the expression will be less than zero. 3. Unary negate (-) on an unsigned type yields an unsigned type, and similary for signed types. 4. As a consequence of usual arithmetic conversion, we can't compare for equality to some negative number (it would be converted). All tests must be "less than zero". 5. We can't create an expression which would overflow if it were signed arithmetic, as this is undefined behavior. */ void t1() { /* 0x7fffffff is a *signed long* (assuming 16-bit int and 32-bit long) */ if (-0x7fffffff < 0) puts("0x7fffffff is signed"); else puts("0x7fffffff is unsigned - problem"); /* But with suffix U, it's *unsigned long* */ if (-0x7fffffffU < 0) puts("0x7fffffffU is signed - problem"); else puts("0x7fffffffU is unsigned"); } void t2() { /* 0x80000001 is an *unsigned long* */ if (0x80000001 < 0) puts("0x80000001 is signed - problem"); else puts("0x80000001 is unsigned"); if (0x80000001U < 0) puts("0x80000001U is signed - problem"); else puts("0x80000001U is unsigned"); } void t3() { /* 0xffffffff is an *unsigned long* */ if (0xffffffff < 0) puts("0xffffffff is signed - problem"); else puts("0xffffffff is unsigned"); if (0xffffffffU < 0) puts("0xffffffffU is signed - problem"); else puts("0xffffffffU is unsigned"); /* 0xffffffffL is an *unsigned long*, despite the lack of a 'U' */ if (0xffffffffL < 0) puts("0xffffffffL is signed - problem"); else puts("0xffffffffL is unsigned"); } int main() { t1(); t2(); t3(); return 0; }