关于"潜在空取消引用"的Clang错误.

bbr*_*own 48 cocoa clang-static-analyzer

我在以下类型的代码中不断出现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;
    }
}
Run Code Online (Sandbox Code Playgroud)

撇开这个例子的完全人为的性质(Clang确实反对,所以它足够说明),Clang在错误分配线上喋喋不休地提出以下异议:

潜在的空取消引用.根据"创建和返回NSError对象"中的编码标准,参数"错误"可以为空.

我喜欢原始的Clang报告.我已经阅读了所引用的文件,我看不到做出预期的方法; 我检查了一些开源的Cocoa库,这似乎是一个常见的习惯用法.有任何想法吗?

Dan*_*tin 98

在该文件的清单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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Jim*_*eia 17

Cocoa约定是返回值应该指示成功或失败(在这种情况下,您为失败返回nil)并且错误被填入其他信息,但仅在调用者请求它时.

换一种说法

NSError *error = nil;
NSString *result = [self checkForLength: aString error: &error];
Run Code Online (Sandbox Code Playgroud)

NSString *result = [self checkForLength: aString error: NULL];
Run Code Online (Sandbox Code Playgroud)

都是调用方法的有效方法.所以方法体应该总是检查一个NULL错误参数:

if (error != NULL)
    *error = ...;
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,传入nil而不是NULL是否有效?这两个值都等于(void*)0 - 这至少是预处理的Objective-C文件所说的. (3认同)