Почему только NSLog предупреждает меня об использовании спецификатора формата строки lu для NSUInteger?
По какой-то причине я получаю ошибку компиляции, когда пытаюсь сделать следующее:
NSLog(@"row: %lu", indexPath.row);
где row
имеет тип NSUInteger
. Ошибка, которую я получаю, это
Conversion указывает тип "unsigned long", но аргумент имеет тип "NSUInteger" (aka "unsigned int" )
Я могу сделать следующее без ошибок компиляции:
NSString * string = [NSString stringWithFormat:@"row: %lu", indexPath.row];
Я использую точно такую же строку формата и аргумент подстановки в обоих случаях, но почему NSLog
freak out в то время как -stringWithFormat:
кажется совершенно удовлетворительным? Мой компилятор - LLVM 1.6.
Ответы
Ответ 1
Все устройства, к которым в настоящее время работает iOS, являются 32-разрядными. Если вы хотите отключить предупреждение:
NSLog(@"row: %lu", (unsigned long)indexPath.row);
[Edit: Начиная с iPhone 5s, уже не так, что iOS всегда 32-разрядная.]
Ответ 2
Я столкнулся с этой же проблемой, и хотя @Wevah верен, и его ответ работает очень хорошо, есть еще один вариант, который не требует каких-либо изменений кода. Подробнее см. В следующей документации Apple:
Руководство по программированию струн | Зависимости платформы
64-разрядное руководство по переходу для Cocoa | Создание 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
делает компилятор (и разработчик) счастливым, но аппаратное обеспечение не заботится, так как он просто выполняет математику в обоих случаях.: -)
Ответ 3
Документация Apple рекомендует отличать 64-битное значение до 32-битного значения, используя% lu и% ld. Это создает проблему, если вы фактически используете дополнительные 32 бита. Строки формата% qu и% qd указывают 64-битное значение (без знака и подпись соответственно). Если вам нужен код, который будет компилироваться в любом из режимов, то значения, объявленные как NSUInteger или NSInteger, должны быть приведены к UInt64 или SInt64 в списке параметров, чтобы избежать предупреждения.