Мне нужно добавить вычисление CRC в мое приложение, и я нашел образец проекта ZipBrowser от Apple.В этом проекте используется функция CRC внутри zlib.h:
#import <zlib.h>
static inline uint32_t _crcFromData(NSData *data) {
uint32_t crc = crc32(0, NULL, 0);
return crc32(crc, [data bytes], [data length]);
}
(потому что я не совсем понимаю значение static inline
). Я думал, что сделаю функцию похожей на типичный Objective-CМетод:
- (uint32_t)_crcFromData:(NSData *)data
{
uint32_t crc = crc32(0, NULL, 0);
return crc32(crc, [data bytes], [data length]);
}
Это дает разные ответы от static inline
!Почему это так?
Кроме того, оба дают мне предупреждения компилятора "Неявное преобразование теряет целочисленную точность".
Далее я разыгрываю crc32
и [data length]
(например, return (uint32_t)crc32...
).Предупреждения компилятора, конечно, исчезли, но возвращаемые значения по-прежнему отличаются от static inline
.
. Я снова удалил приведение, потому что я не уверен, будет ли CRC чувствительным к изменениям ширины переменных.Я использую (так что теперь он выглядит точно так же, как код, вставленный выше).
(Используя NSLog
, кажется, что разница возникает, когда я звоню crc32(crc, [data bytes], [data length]);
, а не , когда я возвращаюсьзначение из static inline
функции или метода Obj-C. Другими словами, кажется, что имеет значение, где вы вызываете функцию zlib из .)
Далее я нашел пример кода для добавления алгоритма CRC в качестве категории NSData
, и я использовал этот код для сравнения ответов с моими вызовами zlib.Сравнивая 3 подхода, я получаю разные результаты в зависимости от того, какие данные я передаю (иногда 2 будут совпадать, но не всегда одинаковые 2)!
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForReadingAtPath:@"/Users/steve/Music/iTunes/iTunes Music/pops1/001.mp3"];
NSLog(@"Cocoa style declaration: %u", [self _crcFromData:[fileHandle readDataOfLength:1024]]); //returns: 3157848792
NSLog(@"Static inline declaration: %u", _crcFromData([fileHandle readDataOfLength:1024])); //returns: 4021661486
NSLog(@"Self-coded CRC: %u", [[fileHandle readDataOfLength:1024] crc32]); //returns: 4021661486
NSLog(@"Cocoa style declaration: %u", [self _crcFromData:[fileHandle readDataOfLength:500]]); //returns: 42187130
NSLog(@"Static inline declaration: %u", _crcFromData([fileHandle readDataOfLength:500])); //returns: 42187130
NSLog(@"Self-coded CRC: %u", [[fileHandle readDataOfLength:500] crc32]); //returns: 4168292535
NSLog(@"Cocoa style declaration: %u", [self _crcFromData:[fileHandle readDataOfLength:5000]]); //returns: 2401083626
NSLog(@"Static inline declaration: %u", _crcFromData([fileHandle readDataOfLength:5000])); //returns: 3786034839
NSLog(@"Self-coded CRC: %u", [[fileHandle readDataOfLength:5000] crc32]); //returns: 2526276347
}
Учитывая разные ответы, яПредположим, что самым безопасным подходом является static inline
подход, использованный в примере проекта Apple.
Включение этого в более конкретные вопросы:
- Что такое
static inline
и Objective-Версии C работают по-разному, что приводит к тому, что они получают разные значения от CRC32
? - Каков наилучший способ избежать ошибок компилятора?Использовать разные типы данных (которые не влияют на результат расчета CRC)?Или подавить предупреждения компилятора?
- Если бы я просто подавил предупреждения компилятора, я бы хотел сделать это только для файла.Я нашел статьи (например, http://joshua.nozzi.name/2011/03/per-file-compiler-flags-in-xcode-4/) о том, где выполнить настройку, но нет статьи о как , чтобы выполнить настройку. Я видел длинные списки флагов, таких как
Wpadded
, Wlong-long
, Werror
и т. Д., Но ничего, что говорит мне о том, что мне нужно, и как на самом деле установить его в виде простого текста в настройке для файла в Xcode 4 (например, Wconversion=
что-то? ). - Наконец, и, более того, , который является правильным подходом ? Не должно быть возможности иметь разные значения CRC, иначе это противоречит цели CRC!
Извините за окольный способ, которым я задал этот вопрос, но я пытаюсь дать более полное представление о моей проблеме в случае, если я сделал какое-то базовое неправильное предположение по пути, в результате чего я спросилнеправильные вопросы. Спасибо.
ОБНОВЛЕНИЕ
Пример проекта компилируется отлично, но когда я вставляю этот код в свой собственный проект, я получаю предупреждения компилятора. Кажется, это потому, что этот проект "Неявное преобразование32-битный тип "в настройках сборки установить" Да "Поскольку это касается всего проекта, я думаю, что было бы лучше не использовать это в моем собственном приложении, если я могу сделать это для каждого файла.