ctypesprintfcompiler-warnings32bit-64bit

Unexpected compiler warning - printf format specifiers


I have the following warning generated by a printf():

warning: format '%llu' expects argument of type 'long long unsigned int', but argument 7 has type 'uint64_t' {aka 'long unsigned int'} [-Wformat=]

Although I want to create a warning-free code, I think that the compiler is way too over-zealous. Because:

So for any practical purpose, long unsigned and long long unsigned are actually the same thing, right?

Even more, while long unsigned can have 32bits on some platforms (e.g., Widows), long long unsigned is highly unlikely to have another number of bits (than 64). long long was created especially to support 64 bits.

So what is going on? How should I proceed? What should I understand?


Side question:

Let's assume that the following is true:

typedef long unsigned int uint64_t;

And let's assume that on some platform, long unsigned becomes 32 bits, and in that case, long long unsigned is not anymore the same as long unsigned. But then uint64_t is not 64 bits anymore - which means that the definition of uint64_t will have to change to remain 64 bits. So in the end, long long unsigned and uint64_t will still be the same size and sign-ness.

So is my thinking correct, that the compiler should not have given me that message at all? Because it is not applicable, no matter how things are, or will be?


I currently use Codeblocks with Cygwin C compiler under Windows - in order to have long unsigned of 64 bits, instead of 32.

The command line for compiling (copy-paste):

gcc.exe -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Winline -Wunreachable-code -Wmissing-declarations -Wswitch-enum -Wswitch-default -Wmain -pedantic -Wextra -Wall -m64 -O0 -c Z:/_progs/_progsData/cb/myprog.c -o obj/Debug/myprog.o


Solution

  • The warning underscores a portability issue. Using %llu for a uint64_t would have undefined behavior on architectures where uint64_t is an unsigned long and unsigned long long would have 128 bits, which would make sense if 128-bit arithmetics are supported.

    This would not happen on legacy systems where long is still 32 bits, but the C Standard does support this possibility.

    You can fix the code in different ways: