2010-12-10 4 views
117

NSInteger은 32 비트 플랫폼에서는 32 비트이고 64 비트 플랫폼에서는 64 비트입니다. 항상 NSInteger 크기와 일치하는 NSLog 지정자가 있습니까?NSInteger에 대한 NSLog/printf 지정자?

설정

  • 엑스 코드 3.2.5
  • LLVM 1.6 컴파일러 (이 중요하다 GCC는이 작업을 수행하지 않습니다)
  • GCC_WARN_TYPECHECK_CALLS_TO_PRINTF 나를 일으키는 그

켜져 어떤 슬픔은 여기 :

#import <Foundation/Foundation.h> 

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

32 비트 코드의 경우 %d 지정자가 필요합니다. 그러나 내가 %d 지정자를 사용하면, 대신 %ld을 사용하도록 제안하면서 64 비트 용으로 컴파일 할 때 경고 메시지가 나타납니다.

%ld을 64 비트 크기와 일치 시키려면 32 비트 코드 용으로 컴파일 할 때 %d을 사용하라는 경고가 표시됩니다.

한 번에 두 경고를 모두 수정하는 방법은 무엇입니까? 거기에서 사용할 수있는 지정자가 있습니까?

이것은 또한 [NSString stringWithFormat:][[NSString alloc] initWithFormat:]에 영향을줍니다.

답변

274

업데이트 답 : 현재 엑스 코드와

, 당신은 zt 수식의 사용은 아키텍처에 따라, 경고없이 NSIntegerNSUInteger를 처리 할 수 ​​있습니다.

부호가있는 경우 %zd을, 부호가없는 경우 %tu을, 16 진수로는 %tx을 사용하려고합니다.

이 정보는 Greg Parker의 호의에 제공됩니다.


원래 대답은 :

official recommended approach은 지정자로 %ld을 사용하고 long에 실제 인수를 캐스팅하는 것입니다.

+6

이것은 확실히가는 길입니다.하지만 정적 인라인 NSIntToLong (NSInteger i) {return (long) i;}'을 사용하는 것이 좋습니다.이렇게하면 유형 검사가 완전히 비활성화되지 않습니다 (즉, i 유형이 변경되는 경우). –

+3

@ steven-fisher의 좋은 생각. 'static inline long NSIntToLong (NSInteger i) {return (long) i;}' – Erik

+2

또한 NSNumber를 생성하고 기록 할 수 있습니다. 'NSLog (@ "% @", @ (mynsint));'http://stackoverflow.com/questions/20355439/nsinteger-and-nsuinteger-in-a-mixed-64bit-32bit-environment – orkoden

0

포매터는 표준 UNIX/POSIX printf 기능을 사용합니다. 부호 오래 오래에 대한 부호없는 긴, 오래 오래 긴 %의 LLD에 대한 %의 신분증 및 % LLU에 대한 % 루를 사용합니다. 콘솔에서 man printf를 시도해보십시오. 그러나 Mac에서는 불완전합니다. Linux 맨 페이지가 더 명시적임 http://www.manpages.info/linux/sprintf.3.html

두 경고는 NSLog (@ "% lu", unsigned long) arg에 의해서만 수정할 수 있습니다. 코드가 32 비트 및 64 비트로 컴파일 될 때 캐스팅과 결합됩니다. 그렇지 않으면 각 컴파일이 별도의 경고를 작성합니다.

관련 문제