37

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);
zx485
  • 28,498
  • 28
  • 50
  • 59
Andrei
  • 8,606
  • 10
  • 35
  • 43
  • 1
    Apparently I need #if defined(WIN32) && !defined(PRId64 ) \n #define PRId64 "I64d" \n #endif. Thanks everybody who answered. – Andrei Jun 10 '11 at 05:53
  • you should also look into your types and have a `typedef` to replace `[u]int64_t` if they are not available. – Jens Gustedt Jun 10 '11 at 06:34
  • what's the difference between 64 bit integer and long? I am reading other's program and they use PRId64, which I don't understand. – 1a1a11a Mar 22 '16 at 13:36

4 Answers4

52

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);
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
  • 1
    You didn't say the exact type you were printing, but as others have noted, `PRId64` is specifically for `int64_t`. If you use `` there is supposed to be a corresponding `` macro for printf. – DigitalRoss Jun 09 '11 at 21:20
  • 1
    I would like to accept both answers, DigitalRoss's and Random832's, don't know how to do it. Files request on meta forum. – Andrei Jun 13 '11 at 20:48
  • Late comment, but I missed that I still needed the `%` in the string before the `PRId64`, or else it complained about `some_64_bit_expression` being unexpected: `printf("Foo %" PRId64, some_64_bit_expression);` – OnlineCop Nov 29 '17 at 16:32
2

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)

Random832
  • 37,415
  • 3
  • 44
  • 63
  • Looks like MS added the `ll` modifier support to msvcrt.dll (at least on my Win7 box). I'm surprised by this. It doesn't look like MinGW did anything special to support it (and last time I tried using `ll` with MinGW it failed miserably). – Michael Burr Jun 10 '11 at 00:30
  • Thanks. I never knew that MSVC supported %lld. – Andrei Jun 10 '11 at 06:01
  • I would like to accept both answers, DigitalRoss's and Random832's, don't know how to do it. Files request on meta forum. – Andrei Jun 13 '11 at 20:48
1

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)
    );
Aleksander Alekseev
  • 1,854
  • 4
  • 25
  • 57
  • 1
    "%u%09u" will unfortunately format 16 as 000000016, which might look as an octal number at worst and weird at best. – PypeBros Nov 28 '19 at 16:07
1

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.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177