Printing unsigned long long int Value Type Returns Strange Results
c, printf, syntax, unsigned-long-long-int
Solution
This is wrong:
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
You use a `unsigned long long` format specifier, but you pass an `int` and an `unsigned long` value. Promotion rules mean you can be sloppy for everything `int`-sized or smaller, which does not apply to `long long`.
Use casts:
printf("unsigned long long int: \n%llu to %llu \n\n",
0ULL, (unsigned long long) ULONG_MAX);
Explanation: When passing arguments to `printf`, any type that can fit in an `int` is promoted to `int`, and then any type that can fit in an `unsigned int` is promoted to `unsigned int`. It is also okay to pass an unsigned type to a signed format specifier or vice versa as long as the value passed can be represented using the type specified by the format specifier.
So you must be careful with `long` and `long long`, but you can be sloppy with `int`, `short`, and `char`.
Most compilers have settings to make them warn you about this type of error, since it can be detected at compile-time fairly easily; GCC and Clang have `-Wformat` which results in the following warnings:
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’
Problem
I have a problem while using the `printf` function to print values of type `unsigned long long int` I have no idea what's wrong. I'm using Dev-Cpp 4.9.9.2 and Visual Studio 2010 Professional (I know that it's not C compiler, but anyway, wanted to try) on Windows 7 Professional 64-bit. For displaying, I used `%llu` modifier (according to How do you printf an unsigned long long int(the format specifier for unsigned long long int)?) but I also tried I64d with no effect... Firstly, I just wanted to print minimum and maximum value of `unsigned long long int` (using `ULONG_MAX` from `limits.h`) ``` printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX); ``` Returns: unsigned long long int: 18446744069414584320 to 1580552164021 (Dev-Cpp) unsigned long long int: 18446744069414584320 to 0 (Visual Studio) Then I tried to using `printf` to print two zeros ``` printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0); ``` Returns: unsigned long long int: 0 to 1580552164021 (Dev-Cpp) unsigned long long int: 0 to 0 (Visual Studio) Also tried two `ULONG_MAX` values ``` printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX); ``` Returns: unsigned long long int: 18446744073709551615 to 1580552164021 (Dev-Cpp) unsigned long long int: 18446744073709551615 to 0 (Visual Studio) Why does it behave like that? Could you explain it to me?