2

Giving the following example:

- (BOOL) doSomething: (NSError**) pError
{
    *pError = [NSError ....];
}

Analyzer will return the following error:

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

To which the suggestion would be to change this to:

- (BOOL) doSomething: (NSError**) pError
{
    if(pError)
    {
        *pError = [NSError ....];
    }
}

But I would prefer to add a nonnull attribute to the error parameter to discourage the use of passing a null. I cannot figure out how to get the arguments to this correct. Is it possible for a double pointer to have a nonnull attribute?

matt
  • 515,959
  • 87
  • 875
  • 1,141
Kyle
  • 17,317
  • 32
  • 140
  • 246

1 Answers1

4

But I would prefer to add a nonnull attribute to the error parameter to discourage the use of passing a null.

The syntax you're looking for is shown in various Stack Overflow answers, such as Objective-C nullability for output parameters. So you could declare, for example:

(NSError * _Nullable * _Nonnull)

...and the desired warning would appear:

enter image description here

I would suggest instead, however, that you simply stop preferring that. The analyzer is quite right about the pattern; you should listen to what it's telling you.

The standard full pattern for calling a method that returns NSError by indirection is, for example:

NSString* path = // ... whatever;
NSStringEncoding enc = // ... whatever;
NSError* err = nil;
NSString* s =
    [NSString stringWithContentsOfFile:path encoding:enc error:&err];
if (nil == s) // oops! something went wrong...

But let's say I'm absolutely certain that this is going to work. Then it is legal to say:

NSString* path = // ... whatever;
NSStringEncoding enc = // ... whatever;
NSString* s =
    [NSString stringWithContentsOfFile:path encoding:enc error:nil];

You should not rule this out; it's reasonable and normal.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 1
    Even this is – of course – a great answer, I want to add, that `nil` is not `NULL`. `nil` is always an reference to an (no) *object*, while `NSError**` does *not* point to an (no) *object*. – Amin Negm-Awad Feb 15 '18 at 05:08
  • `I would suggest instead, however, that you simply stop preferring that.`. Thanks, honestly I needed that beat into my head and your comment did just that. I also appreacheate that instead of just saying that you took the time to answer the underlying question (although I will follow the proper solution). – Kyle Feb 15 '18 at 12:36