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?

Original source

Related problems