Спецификатор NSLog / printf для NSInteger? - PullRequest
125 голосов
/ 10 декабря 2010

A NSInteger - 32 бита на 32-битных платформах и 64 бита на 64-битных платформах. Существует ли спецификатор NSLog, который всегда соответствует размеру NSInteger?

Настройка

  • Xcode 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, я получаю предупреждение при компиляции для 64-битной системы, предлагая вместо этого использовать %ld.

Если я использую %ld для соответствия 64-битному размеру, при компиляции для 32-битного кода я получаю предупреждение, предлагающее использовать %d вместо.

Как исправить оба предупреждения одновременно? Могу ли я использовать спецификатор, который работает на любом из них?

Это также влияет на [NSString stringWithFormat:] и [[NSString alloc] initWithFormat:].

Ответы [ 2 ]

287 голосов
/ 10 декабря 2010

Обновленный ответ:

С текущим Xcode вы можете использовать модификаторы z и t для обработки NSInteger и NSUInteger без предупреждений на всех архитектурах.

Вы хотите использовать %zd для подписанного, %tu для неподписанного и %tx для шестнадцатеричного.

Эта информация предоставлена ​​ Грегом Паркером .


Оригинальный ответ:

Официальный рекомендуемый подход заключается в использовании %ld в качестве спецификатора и приведении фактического аргумента к long.

0 голосов
/ 16 декабря 2014

Форматтеры поступают из стандартной функции printf UNIX / POSIX.Используйте % lu для unsigned long ,% ld для long,% lld для long long и % llu для unsigned long long .Попробуйте man printf на консоли, но на Mac это неполно.Страницы man linux более понятны http://www.manpages.info/linux/sprintf.3.html

Оба предупреждения могут быть исправлены только NSLog (@ "% lu", (unsigned long) arg);в сочетании с приведением в качестве кода будут скомпилированы в 32 И 64 бит для iOS.В противном случае каждая компиляция создает отдельное предупреждение.

...