Подтвердить что ты не робот

Ошибка Clang на "Потенциальное нулевое разыменование".

Я продолжаю получать ошибки Clang в следующем типе кода, и я не могу понять, почему они ошибочны или как их решить для удовлетворения Clang:

+ (NSString *)checkForLength: (NSString *)theString error: (NSError **)error {
    BOOL hasLength = ([theString length] > 0);
    if (hasLength) return theString;
    else {
        *error = [NSError errorWithDomain:@"ErrorDomain" code:hasLength userInfo:nil];
        return nil;
    }
}

Оставив в стороне совершенно надуманный характер примера (который Кланг сделал так, чтобы он был достаточно иллюстративным), Клэнг отказывается в строке назначения ошибок со следующим возражением:

Потенциальное нулевое разыменование. Согласно стандартам кодирования в разделе "Создание и возврат NSError объектов" параметр "ошибка" может быть нулевым.

Мне нравится иметь чистый отчет Clang. Я прочитал цитированный документ, и я не вижу способа делать то, что ожидалось; Я проверил некоторые библиотеки с открытым исходным кодом Cocoa, и это, похоже, является распространенной идиомой. Любые идеи?

4b9b3361

Ответ 1

Как сделать то, что ожидается, показано в листинге 3-5 в этом документе. С вашим примером кода:

+ (NSString *)checkForLength: (NSString *)theString error: (NSError **)error {
    BOOL hasLength = ([theString length] > 0);
    if (hasLength) return theString;
    else {
        if (error != NULL) *error = [NSError errorWithDomain:@"ErrorDomain" code:hasLength userInfo:nil];
        return nil;
    }
}

Ответ 2

Соглашение Cocoa заключается в том, что возвращаемое значение должно указывать на успех или неудачу (в этом случае вы возвращаете nil для отказа), а ошибка заполняется дополнительной информацией, но только тогда, когда вызывающий абонент запрашивает ее.

Другими словами

NSError *error = nil;
NSString *result = [self checkForLength: aString error: &error];

и

NSString *result = [self checkForLength: aString error: NULL];

являются действительными способами вызова метода. Поэтому тело метода должно всегда проверять параметр ошибки NULL:

if (error != NULL)
    *error = ...;