Warum ist auf meinem 64-Bit-Mac (ich verwende Clang) der uint64_t
-Typ unsigned long long
, während bei 64-Bit-Ubuntu der uint64_t
-Typ unsigned long
ist?
Das macht es sehr schwierig für mich, meine printf
-Aufrufe dazu zu bringen, in beiden Umgebungen keine Compilerwarnungen zu geben (oder sogar zu arbeiten).
Ich kann versuchen, Makros zu verwenden, um zu versuchen, die korrekte Zeichenkette ( #define LU
entweder %llu
oder %lu
, und dabei die printf
Zeichenketten ein wenig zu ändern), aber auf dem Mac, den ich habe eine 64-Bit-Wortgröße (also _LP64
wäre definiert und UINTPTR_MAX != 0xffffffff
) und trotzdem verwendet sie long long
für die 64-Bit-int-Typen.
Die Makros sind bereits für Sie in <cinttypes>
definiert. Probieren Sie
Oder, noch besser, verwenden Sie C ++ - Funktionen wie
%Vor%welches die richtige & lt; & lt; Operator für Ihren Variablentyp.
Der zugrunde liegende Typ von uint64_t
kann unabhängig von der Implementierung so lange sein, wie es tatsächlich 64 Bits sind.
Offensichtlich in C ++ ist die bevorzugte Lösung, Iostreams anstelle von printf
zu verwenden, da dann das Problem verschwindet. Sie können jedoch immer den Wert übergeben, der an printf
übergeben wurde, um den Typ immer korrekt zu machen:
printf("%llu", static_cast<unsigned long long>(value));
Leider ist die Norm nicht sehr spezifisch für die Größen dieser Typen ... Die einzige Garantie ist, dass sizeof(int) <= sizeof(long) <= sizeof(long long)
.
Sie können Makros verwenden, wie Sie es gesagt haben, oder Sie könnten %zu
oder %ju
verwenden, um size_t
und uintmax_t
Typen auszudrucken (beide 64-Bit unter OS X, nicht getestet) auf Ubuntu). Ich denke nicht, dass es andere Möglichkeiten gibt.
Ich bin sicher, andere Leute werden dir sagen, dass du BOOST benutzen sollst. Also im Interesse einer Lösung, die nicht von BOOST abhängig ist:
Ich bin so oft auf das gleiche Problem gestoßen, dass ich aufgegeben habe und meine eigenen Hilfsmakros geschrieben habe, die in% s statt irgendeiner Marke von %llu
oder %lu
oder was auch immer einspeisen. Ich fand es auch hilfreich für die Aufrechterhaltung eines vernünftigen Formatzeichenkettenentwurfs und für bessere (und konsistentere) Hex- und Zeigerausdrucke. Es gibt zwei Vorbehalte:
Sie können nicht einfach zusätzliche Formatierungsparameter kombinieren (Recht-linksbündige Ausrichtung, Auffüllung usw.) - aber das können Sie auch nicht wirklich mit dem Makro LU
tun.
Dieser Ansatz fügt der Aufgabe zum Formatieren und Drucken von Zeichenfolgen zusätzlichen Aufwand hinzu. Ich schreibe jedoch performancekritische Anwendungen, und ich habe nicht bemerkt, dass dies ein Problem ist, außer in den Visual C ++ - Debug-Builds von Microsoft (die aufgrund all der internen Überprüfungs- und Korrektheitsprüfungen etwa 200x mehr Zeit benötigen, um den Heapspeicher zuzuordnen und freizugeben).
Hier ist ein Vergleich:
%Vor%gegen
%Vor%Damit es funktioniert, habe ich eine Reihe von Makros und Vorlagen wie folgt verwendet:
%Vor%Meine String-Formatierungsfunktionen basieren auf der jetzt bevorzugten Methode, direkt in eine std :: string zu formatieren, die ungefähr so aussieht:
%Vor%Tags und Links c++ macos integer types long-integer