Here is what I did,
#include <stdio.h>
#define SIZE_T_MAX ((size_t) -1)
#define UCHAR_MAX ((unsigned char) -1)
#define USHORT_MAX ((unsigned short) -1)
#define UINT_MAX ((unsigned int) -1)
int main()
{
printf("SIZE_T_MAX %d\n", SIZE_T_MAX);
printf("UCHAR_MAX %d\n", UCHAR_MAX);
printf("USHORT_MAX %d\n", USHORT_MAX);
printf("UINT_MAX %d\n", UINT_MAX);
}
The "%d" format expects a signed int argument. In the first call
you're passing an unsigned value and telling printf that it's a signed
value. If you lie to printf, it will probably lie to you.
The printf function has know way of knowing the types of the arguments
you pass it; the only information it has is is the format string.
Getting the types right is entirely the caller's responsibility.
Try this instead:
#include <stdio.h>
#define MY_SIZE_T_MAX ((size_t) -1)
#define MY_UCHAR_MAX ((unsigned char) -1)
#define MY_USHORT_MAX ((unsigned short) -1)
#define MY_UINT_MAX ((unsigned int) -1)
int main()
{
printf("MY_SIZE_T_MAX %lu\n", (unsigned long)MY_SIZE_T_MAX);
printf("MY_UCHAR_MAX %u\n", (unsigned)MY_UCHAR_MAX);
printf("MY_USHORT_MAX %u\n", (unsigned)MY_USHORT_MAX);
printf("MY_UINT_MAX %u\n", MY_UINT_MAX);
return 0;
}
I prefixed all the macros with "MY_", since some of them conflict with
names in <limits.h> (which you didn't #include, but it's best to avoid
re-declaring identifiers declared in standard headers).
I cast MY_SIZE_T_MAX to unsigned long (since it may be bigger than
unsigned int on some platforms), and used the appropriate format.
MY_UCHAR_MAX and MY_USHORT_MAX are guaranteed to fit in an unsigned
int, so I used that rather than unsigned long, and of course
MY_UINT_MAX is already an unsigned int.
On one system, the revised program gave me the following output (other
systems may vary):
MY_SIZE_T_MAX 4294967295
MY_UCHAR_MAX 255
MY_USHORT_MAX 65535
MY_UINT_MAX 4294967295