在“潜在零引用”上发出铿锵错误。

时间:2021-10-09 19:39:06

I keep getting Clang errors on the following type of code and I can't figure out why they're erroneous or how to resolve them to Clang's satisfaction:

我在以下类型的代码中不断地收到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;
    }
}

Leaving aside the utterly-contrived nature of the example (which Clang did object to so it's illustrative enough), Clang balks at the error assignment line with the following objection:

撇开这个示例的精心设计的本质(Clang确实反对这个示例,因此它具有足够的说明性)不谈,Clang在错误赋值线上犹豫不前,并提出以下反对意见:

Potential null dereference. According to coding standards in 'Creating and Returning NSError Objects' the parameter 'error' may be null.

潜在的零废弃。根据“创建和返回NSError对象”的编码标准,参数“error”可以为空。

I like having a pristine Clang report. I've read the cited document and I can't see a way to do what's expected; I checked some open-source Cocoa libraries and this seems to be a common idiom. Any ideas?

我喜欢有一份质朴的报告。我读过被引用的文件,但我不知道该怎么做;我查看了一些开源的可可库,这似乎是一个常见的习惯用法。什么好主意吗?

2 个解决方案

#1


95  

The way to do what's expected is shown in listing 3-5 in that document. With your example code:

实现预期目标的方法如该文档中的清单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


16  

The Cocoa convention is that the return value should indicate success or failure (in this case, you return nil for failure) and the error is filled in with additional information, but only when the caller requests it.

Cocoa约定是返回值应该表示成功或失败(在这种情况下,您返回nil作为失败),并且错误被填入额外的信息,但只有当调用者请求时。

In other words

换句话说

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

and

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

are both valid ways to invoke the method. So the method body should always check for a NULL error param:

都是调用方法的有效方法。因此,方法主体应该始终检查空错误参数:

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

#1


95  

The way to do what's expected is shown in listing 3-5 in that document. With your example code:

实现预期目标的方法如该文档中的清单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


16  

The Cocoa convention is that the return value should indicate success or failure (in this case, you return nil for failure) and the error is filled in with additional information, but only when the caller requests it.

Cocoa约定是返回值应该表示成功或失败(在这种情况下,您返回nil作为失败),并且错误被填入额外的信息,但只有当调用者请求时。

In other words

换句话说

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

and

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

are both valid ways to invoke the method. So the method body should always check for a NULL error param:

都是调用方法的有效方法。因此,方法主体应该始终检查空错误参数:

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