Search code examples
objective-c++objective-c-nullability

Nullability rules for C++ objects in Objective-C++


(Please edit this post if I use incorrect C++ terms. I'm a total C++ noob.)

How does Objective-C nullability work with C++ objects in an Objective-C++ class?

For example, given the following type and function:

typedef struct
{
    const Foo* fooArray;
    uint32_t fooArrayLength;

} FooList;

uint32_t GetFoo(const std::string& bar, std::shared_ptr<const FooList>& result);

Is it legal to redefine GetFoo thusly?

uint32_t GetFoo(const std::string& _Nonnull bar, std::shared_ptr<const FooList _Nullable>& _Nonnull result);

Will I get any warnings from either clang or the static analyzer if I call GetFoo thusly?

GetFoo(nil, nil);

Solution

  • You've picked the two C++ cases where Nullability makes no sense. :-)

    1. Your const FooList is a non-pointer type, so can never be nullptr (or NULL on older C++ compilers).

    2. References are defined by the standard as never being nullptr either. Which makes sense, because nullptr is a pointer type, and the only way to go from a nullptr to a reference is dereferencing it, which ... well, nobody knows what happens when you dereference a null pointer.

    However, the only case where you didn't specify nullability (the const Foo* in the struct) is actually where it would be valid.

    At least if you're running on Apple's compilers. Technically, Apple's nullability is only part of the Objective-C (and by extension Objective-C++) standards, so is a nonstandard extension to C++ that depends on the compiler (hence the underscore at its start, which is reserved for compiler-specific keywords).

    NB - For performance reasons, most C++ compilers just implement references as syntactic sugar on top of pointers, so in practice, you could do something evil like

    Foo* myFoo = nullptr;
    Foo& myFooRef = *myFoo;
    

    and they wouldn't know you just made a nullptr reference, but that falls under "undefined" behaviour and as such is wrong code. However, I don't know if any Objective-C++ compiler currently analyzes nullability on C++ references. A quick test shows Apple's at least doesn't. Not sure if the static analyzer catches it either.

    PS - If you tried to compile the above code, you should get an error about use of _Nullable (sic) on a non-pointer type.