2010-12-10 18 views
117

Ein NSInteger ist 32 Bit auf 32-Bit-Plattformen und 64 Bit auf 64-Bit-Plattformen. Gibt es einen NSLog Spezifizierer, der immer der Größe von NSInteger entspricht?NSLog/printf-Spezifizierer für NSInteger?

Setup-

  • Xcode 3.2.5
  • llvm 1.6 Compiler (dies ist wichtig, gcc tut dies nicht)
  • GCC_WARN_TYPECHECK_CALLS_TO_PRINTF eingeschaltet

Das bin ich verursacht einige Trauer hier:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 
    @autoreleasepool { 
     NSInteger i = 0; 
     NSLog(@"%d", i); 
    } 
    return 0; 
} 

Für 32-Bit-Code benötige ich den %d Spezifizierer. Aber wenn ich den %d Spezifizierer verwende, erhalte ich eine Warnung, wenn ich für 64 Bit kompiliere, was vorschlägt, dass ich stattdessen %ld benutze.

Wenn ich %ld verwenden, um die 64-Bit-Größe anzupassen, bekomme ich beim Kompilieren für 32-Bit-Code eine Warnung, die darauf hinweist, dass ich stattdessen %d verwende.

Wie kann ich beide Warnungen gleichzeitig beheben? Gibt es einen Spezifizierer, den ich verwenden kann? Dies betrifft auch [NSString stringWithFormat:] und [[NSString alloc] initWithFormat:].

Antwort

274

Aktualisiert Antwort:

Mit aktuellen Xcode können Sie die Verwendung der z und t Modifikatoren machen NSInteger und NSUInteger ohne Warnungen zu handhaben, auf allen Architekturen.

Sie möchten %zd für signiert, %tu für unsigned und %tx für hex.

Diese Information wurde mit freundlicher Genehmigung von Greg Parker.


Ursprüngliche Antwort:

Die official recommended approach ist %ld als Bezeichner zu verwenden, und das eigentliche Argument einer long zu werfen.

+6

Dies ist definitiv der Weg zu gehen, aber ich denke, ich könnte 'statische Inline NSIntToLong (NSInteger i) {zurück (lang) ich;}'.Dies vermeidet eine vollständige Deaktivierung der Typprüfung (d. H. Wenn sich der Typ von i ändert). –

+3

Gutes Denken von @ steven-fisher. Vermeiden Sie eine Warnung mit: 'static inline long NSIntToLong (NSInteger i) {return (long) i;}' – Erik

+2

Sie können auch eine NSNumber erstellen und diese protokollieren. 'NSLog (@"% @ ", @ (mynsint));' http://stackoverflow.com/questions/20355439/nsinteger-and-nsuinteger-in-a-mixed-64bit-32bit-umgebung – orkoden

0

Die Formatierer stammen aus der Standard-UNIX/POSIX-printf-Funktion. Verwenden Sie % lu für unsigned long,% ld für lange,% LLD für lange lange und % llu für unsigned long long. Versuchen Sie man printf auf der Konsole, aber auf dem Mac ist es unvollständig. Die Linux-Manpages sind expliziter http://www.manpages.info/linux/sprintf.3.html

Beide Warnungen können nur von NSLog (@ "% lu", (unsigned lang) arg) behoben werden; kombiniert mit einem Cast, da der Code in 32 UND 64 Bit für iOS kompiliert wird. Andernfalls erstellt jede Kompilierung eine separate Warnung.

Verwandte Themen