Почему CRC возвращает другое значение, когда внутри метода Objective-C вместо статической встроенной функции? - PullRequest
2 голосов
/ 07 августа 2011

Мне нужно добавить вычисление 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-битный тип "в настройках сборки установить" Да "Поскольку это касается всего проекта, я думаю, что было бы лучше не использовать это в моем собственном приложении, если я могу сделать это для каждого файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...