cross-platform printing of 64-bit integers with printf

May 2024 ยท 2 minute read

In Windows, it is "%I64d". In Linux and Solaris, it is "%lld".
If I want to write cross-platform printfs that prints long long values: what is good way of doing so ?

long long ll; printf(???, ll); 
3

4 Answers

There are a couple of approaches.

You could write your code in C99-conforming fashion, and then supply system-specific hacks when the compiler-writers let you down. (Sadly, that's rather common in C99.)

#include <stdint.h> #include <inttypes.h> printf("My value is %10" PRId64 "\n", some_64_bit_expression); 

If one of your target systems has neglected to implement <inttypes.h> or has in some other way fiendishly slacked off because some of the type features are optional, then you just need a system-specific #define for PRId64 (or whatever) on that system.

The other approach is to pick something that's currently always implemented as 64-bits and is supported by printf, and then cast. Not perfect but it will often do:

printf("My value is %10lld\n", (long long)some_64_bit_expression); 
3

MSVC supports long long and ll starting Visual Studio 2005.

You could check the value of the _MSC_VER macro (>= 1400 for 2005), or simply don't support older compilers.

It doesn't provide the C99 macros, so you will have to cast to long long rather than using PRId64.

This won't help if you're using older MSVC libraries with a non-MSVC compiler (I think mingw, at least, provides its own version of printf that supports ll)

3

No on linux and solaris it is only incidentally that this is lld for a 64bit type. C99 prescribes simple (but ugly) macros to make these things portable PRId64. Since some windows compilers don't follow the standard you might be out of luck, there, unfortunately.

Edit: In your example you are using a different thing than a 64bit integer, namely a long long. This could well be 128 on some architectures. Here C99 has typedefs that guarantee you the minimum or exact width of the type (if they are implemented on the platform). These types are found with the inttypes.h header, namely int64_t for a fixe-width 64 bit type represented in two's complement. Maybe or maybe not your windows compiler has this.

2

As alternative you can use code like this:

uint64_t currentTimeMs = ...; printf("currentTimeMs = 0x%08x%08x\n", (uint32_t)(currentTimeMs >> 32), (uint32_t)(currentTimeMs & 0xFFFFFFFF) ); 

Or maybe:

printf("currentTimeMs = %u%09u\n", (uint32_t)(currentTimeMs / 1000000000), (uint32_t)(currentTimeMs % 1000000000) ); 
1

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobWtxaWWFdHvCq6asq12luaLAxaippmWgp7avwMinnmanlmKDdXnBoqtmoZ6psqix0axksKGknXqxvsinq58%3D