简体   繁体   中英

printf() format specifier for int64_t and uint64_t in 32-bit ANSI 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?

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).

One way to ensure you can use a 64 bit integer with a C89 compiler:

#include <stdio.h>
#include <assert.h>
#include <limits.h>
typedef unsigned long uint64_t;

int main() {
    uint64_t some_int = 123456789;
    assert(CHAR_BIT * sizeof(long) >= 64);
    printf("Your int is: %lu\n", some_int);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM