Почему только NSLog предупреждает меня об использовании спецификатора формата строки% lu для NSUInteger? - PullRequest
19 голосов
/ 15 февраля 2011

По какой-то причине я получаю ошибку компиляции, когда пытаюсь сделать следующее:

NSLog(@"row: %lu", indexPath.row);

, где row имеет тип NSUInteger.Я получаю сообщение об ошибке:

Преобразование указывает тип «unsigned long», но аргумент имеет тип «NSUInteger» (он же «unsigned int»)

.без ошибок компиляции:

NSString * string = [NSString stringWithFormat:@"row: %lu", indexPath.row];

Я использую одну и ту же строку формата и аргумент подстановки в обоих случаях, но почему NSLog выходит из себя, в то время как -stringWithFormat: кажется совершенно довольным?Мой компилятор LLVM 1.6.

Ответы [ 3 ]

35 голосов
/ 15 февраля 2011

Все устройства, на которых работает iOS, являются 32-битными. Если вы хотите заставить замолчать предупреждение:

NSLog(@"row: %lu", (unsigned long)indexPath.row);

[Редактировать: Что касается iPhone 5s, больше не правда, что iOS всегда 32-битная.]

6 голосов
/ 15 августа 2012

Я столкнулся с этой же проблемой, и хотя @Wevah правильный и его ответ работает отлично, есть еще один вариант, который не требует никаких изменений кода. Подробности смотрите в следующей документации Apple:

Руководство по программированию строки | Зависимости платформы

64-битное руководство по переходу для какао | Сборка 32-битных, как 64-битных

Макрос препроцессора NS_BUILD_32_LIKE_64 весьма полезен. Вы можете установить его в настройках вашего проекта XCode (в GCC_PREPROCESSOR_DEFINITIONS) или просто поместить #define NS_BUILD_32_LIKE_64 1 в файл скомпилированного заголовка (.pch). В моем приложении это исключило 11 предупреждений без каких-либо изменений кода.

Это работает, потому что unsigned int и unsigned long имеют одинаковый размер (4 байта) на iOS, поэтому изменение typedef на NSUInteger делает компилятор (и разработчика) счастливым, но аппаратное обеспечение не заботится так как он просто делает целочисленную математику в обоих случаях. : -)

0 голосов
/ 03 ноября 2012

В документации Apple рекомендуется преобразовывать 64-битное значение в 32-битное с использованием% lu и% ld. Это создает проблему, если вы действительно используете дополнительные 32 бита. Строки формата% qu и% qd задают 64-битное значение (без знака и со знаком соответственно). Если вам нужен код, который будет компилироваться в любом режиме, то значения, объявленные как NSUInteger или NSInteger, должны быть преобразованы в UInt64 или SInt64 в списке параметров, чтобы избежать предупреждения.

...