0
votes

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?

2
What is known as ANSI C is actually the precursor to the ISO standardization of C. It is also very old and unless you have an equally old compiler you should at least attempt to use the C99 standard. Even Microsoft Visual C compiler support most of C99 these days.Some programmer dude
"it fails..." - what errors do you see?Attie
@tmaxthomas: I get no compiler error for your code with this command line.clemens
Well since uint64_t was introduced in the C99 standard, there's really no portable way to handle 64-bit integers in older compilers. Why do you want to port it to an older standard? Considering that all three of the big compilers (GCC, Clang and MSVC) now support C99 (and all or most of C11 even) since long back, I don't really see a reason for it.Some programmer dude
The term "ANSI C" is commonly used to refer to the language defined by the 1989 ANSI C standard, which is identical to the language defined by the 1990 ISO C standard (which was then adopted by ANSI). The 1999 and 2011 editions of the C standard were published by ISO and then officially adopted by ANSI. So ANSI, the organization, recognizes ISO C11 as the current C standard. Since "ANSI C" is ambiguous, I suggest you refer to the year of a standard. By "ANSI C", I suspect you mean C90 (which can also be called C89).Keith Thompson

2 Answers

2
votes

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

0
votes

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;
}