предупреждение: сравнение всегда верно из-за ограниченного диапазона типов данных вызывает сбой - PullRequest
1 голос
/ 03 сентября 2011

У меня предупреждение, что я не могу найти причину.

Я следую инструкциям в тексте по программированию Какао, который реализует слайд-шоу изображений на основе документов. Это предупреждение приводит к тому, что цикл while выполняется больше, чем правильное количество раз, что приводит к сбою программы. Код, загруженный с сайта автора, не имеет этой проблемы.

Я предположил, что это была простая опечатка в моей версии, но, внимательно читая обе версии кода, я не смог найти никаких отличий. Затем я систематически заменял каждый .h, .m, .xib и другой файл ресурсов в моей версии на авторскую версию, очищая все цели и восстанавливая после каждой замены.

Однако предупреждение не исчезнет, ​​пока я окончательно не заменю файл .xcodeproj на версию автора. В этот момент предупреждение сбрасывается, и код запускается без сбоев. Затем я поэкспериментировал с другим способом, заменив каждый из файлов .h и .m в авторской версии моими файлами .h и .m одновременно, очистил все цели, построил и снова никаких предупреждений или сбоев. Я подумал, что это может быть какой-то параметр в файле .plist, но замена двух версий этого файла, похоже, не имеет никакого эффекта. Кажется, я могу сузить его до файла project.pbxproj в пакете .xcodeproj, но не вижу, как какой-либо из перечисленных там параметров сборки может вызвать проблему.

Буду признателен, если кто-нибудь сможет предложить какое-либо понимание проблемы или порекомендовать метод для ее устранения. Предупреждение и соответствующий сегмент кода с циклом while:

Предупреждение о сборке:

SlideShowDocument.m: In function '-[SlideShowDocument removeSlidesAtIndexes:]':
SlideShowDocument.m:191: warning: comparison is always true due to limited range of data type

Вывод консоли отладчика:

Slide Master[665:a0f] HIToolbox: ignoring exception '*** -[NSCFArray objectAtIndex:]: index (4294967295) beyond bounds (3)' that raised inside

Код:

- (void)removeSlidesAtIndexes:(NSIndexSet*)indexes;
{
    NSMutableArray *slideList = [NSMutableArray array];

    unsigned int index = [indexes firstIndex];

    while (index != NSNotFound) {
        Slide *slide = [mSlides objectAtIndex:index];

        [slideList addObject:slide];

        index = [indexes indexGreaterThanIndex:index];
    }

    if ([slideList count]) {
        //remove the slides from the master list

        [self recordSlideChange];

        [mSlides removeObjectsInArray:slideList];

        [self notifySlidesChanged];
    }
}

1 Ответ

8 голосов
/ 03 сентября 2011

NSUInteger может быть больше, чем unsigned int, и это может зависеть от цели сборки (32 бита против 64 бита, LP64 против ILP64).From NSUInteger :

#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

Если это относится к одной из ваших целей, NSNotFound, что является значением перечисления, равным NSIntegerMax ( см. Здесь ) не поместится в unsigned int.Поэтому в игру вступит некоторое целочисленное продвижение, и вы никогда не достигнете равенства (о чем вам говорит компилятор) в этой строке:

while (index != NSNotFound) {

Объявите index как NSUInteger (типиспользуется NSIndexSet для индексов), и эта проблема должна быть решена переносимо.

...