Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 640
Heath Borders Avatar asked Sep 14 '25 05:09

Heath Borders


2 Answers

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.

like image 173
uliwitness Avatar answered Sep 16 '25 22:09

uliwitness


Jordan Rose (of the Swift team at Apple) says:

References are not pointers, so they don't get nullability. But refs already may never be NULL according to the C++ standard.

So the question is moot.

However, regarding pointers:

[Regular pointers still get nullability in C++ and Objective-C++] (But there are a lot of rough edges around templates, unfortunately. ObjC++ nullability hasn't been a priority.)

like image 30
Heath Borders Avatar answered Sep 16 '25 21:09

Heath Borders