it-swarm.com.de

plattformübergreifender Druck von 64-Bit-Ganzzahlen mit printf

In Windows ist es "% I64d". In Linux und Solaris ist dies "% lld".
Wenn ich plattformübergreifende printfs schreiben möchte, die long long-Werte druckt: Was ist eine gute Möglichkeit, dies zu tun?

long long ll;
printf(???, ll);
23
Andrei

Es gibt einige Ansätze.

Sie könnten Ihren Code C99-konform schreiben und dann systemspezifische Hacks bereitstellen, wenn die Compiler-Writer Sie im Stich gelassen haben. (Leider ist das in C99 ziemlich üblich.)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

Wenn eines Ihrer Zielsysteme die Implementierung von <inttypes.h> versäumt hat oder auf andere Weise schädlich abgenommen hat, da einige der Typmerkmale optional sind, benötigen Sie lediglich einen systemspezifischen #define für PRId64 (oder was auch immer) auf diesem System.

Der andere Ansatz besteht darin, etwas auszuwählen, das derzeit immer als 64-Bit implementiert ist und von printf unterstützt wird. Nicht perfekt, aber es wird oft tun:

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

MSVC unterstützt long long und ll ab Visual Studio 2005 .

Sie können den Wert des Makros _MSC_VER (>= 1400 für 2005) überprüfen oder ältere Compiler nicht unterstützen.

Die C99-Makros werden nicht bereitgestellt. Sie müssen also in long long umwandeln, anstatt PRId64 zu verwenden.

Dies ist nicht hilfreich, wenn Sie ältere MSVC-Bibliotheken mit einem Nicht-MSVC-Compiler verwenden. Mingw bietet zumindest eine eigene Version von printf, die ll unterstützt.

2
Random832

Nein, unter Linux und Solaris ist dies nur für einen 64-Bit-Typ lld. C99 schreibt einfache (aber hässliche) Makros vor, um diese Dinge PRId64 portabel zu machen. Da einige Windows-Compiler nicht dem Standard entsprechen, haben Sie dort leider kein Glück.

Edit: In Ihrem Beispiel verwenden Sie eine andere Sache als eine 64-Bit-Ganzzahl, nämlich einen long long. Bei einigen Architekturen kann dies durchaus 128 sein. Hier hat C99 typedefs, die Ihnen die minimale oder exakte Breite des Typs garantieren (wenn sie auf der Plattform implementiert sind). Diese Typen werden mit dem inttypes.h-Header gefunden, nämlich int64_t für einen 64-Bit-Typ mit fester Breite, der in Zweierkomplement dargestellt wird. Vielleicht oder vielleicht hat Ihr Windows-Compiler dies nicht.

1
Jens Gustedt

Als Alternative können Sie Code wie folgt verwenden:

uint64_t currentTimeMs = ...;

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

Oder vielleicht:

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