printf und% llu vs% lu auf OS X [duplizieren]

8

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.

%Vor%     
Steven Lu 28.12.2012, 18:15
quelle

5 Antworten

5

Die Makros sind bereits für Sie in <cinttypes> definiert. Probieren Sie

aus %Vor%

Oder, noch besser, verwenden Sie C ++ - Funktionen wie

%Vor%

welches die richtige & lt; & lt; Operator für Ihren Variablentyp.

    
Bo Persson 28.12.2012, 18:40
quelle
2

Die Antwort ist, über statische Besetzung zu fördern:

%Vor%     
Grady Player 29.12.2012 06:51
quelle
1

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

    
Mark B 28.12.2012 18:40
quelle
0

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.

    
daxnitro 28.12.2012 18:41
quelle
0

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:

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

  2. 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%     
jstine 28.12.2012 19:12
quelle