Printf() format specifier for int64_t and uint64_t in 32-bit ANSI C

c

I'm writing some 32-bit ANSI C, compiling with gcc, in which I need to print some 64-bit signed and unsigned integers. The problem is that in gcc 32-bit C, int64_t and uint64_t get converted to long long int and unsigned long long int respectively, with format specifier %lld and %llu, which are not supported by ANSI C. Using the format specifier macros provided in inttypes.h don't help either, since those get converted to %lld and %llu.

The following code fails to compile:

#include <stdio.h>
#include <inttypes.h>

int main() {
    uint64_t some_int = 123456789;
    printf("Your int is: %"PRId64"\n", some_int);
    return 0;
}

Compiled with gcc main.c -ansi -Og -g -m32 -Wall -Werror -Wextra -pedantic

Error message is:

error: ISO C90 does not support the ‘ll’ gnu_printf length modifier [-Werror=format=]

So, my question is: What format specifier should I use to print double-length integers in 32-bit ANSI C?

Best Answer

The phrase "ANSI C" commonly refers to the language defined by the 1989 ISO C standard. The 1990 ISO C standard describes exactly the same language (it adds some ISO-mandated sections). ANSI officially dropped its own 1989 standard and adopted the ISO standard -- and has also adopted the 1999 and 2011 editions of the ISO C standard. So the C standard defined by ANSI is the 2011 ISO C standard.

Because of this ambiguity, I suggest avoiding the phrase "ANSI C" and referring to the year in which the standard was published by ISO: C90, C99, or C11.

What format specifier should I use to print double-length integers in 32-bit ANSI C?

There is none.

C90 did not support the and header or the type long long. It did not require support for any 64-bit integer type (long may be 64 bits, but is commonly 32). Because the types didn't exist, printf provided no format specifiers for them.

In principle, you could use a C90 implementation that supports 64-bit long (sacrificing portability), or you could implement your own 64-bit type using an array of narrower integers, providing operations as functions.

If you could update your question to explain exactly why you want to restrict yourself to a 29-year-old version of the C standard, it might be possible to give a more useful answer. I'd tell you simply to use an implementation that support C99 or C11, but you've indicated that's not a solution (without explaining why).