Objective-C++ 中 C++ 对象的可空性规则

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

(如果我使用了不正确的 C++ 术语,请编辑此 post。我是一个彻头彻尾的 C++ 菜鸟。)

Objective-C nullability 如何在 Objective-C++ class 中使用 C++ 对象?

例如,给定以下类型和函数:

typedef struct
{
    const Foo* fooArray;
    uint32_t fooArrayLength;

} FooList;

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

这样重新定义GetFoo合法吗?

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

如果我这样调用 GetFoo,是否会从 clang 或静态分析器收到任何警告?

GetFoo(nil, nil);

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.

所以这个问题没有实际意义。

然而,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.)

您选择了可空性没有意义的两个 C++ 案例。 :-)

  1. 您的 const FooList 是非指针类型,因此永远不会是 nullptr(或 NULL 在旧的 C++ 编译器上)。

  2. 引用由标准定义为永远不会是 nullptr。这是有道理的,因为 nullptr 是指针类型,从 nullptr 到引用的唯一方法是取消引用它,这......好吧,没有人知道当你取消引用 null 时会发生什么指针.

但是,唯一没有指定可空性(结构中的 const Foo*)的情况实际上是有效的。

至少如果您 运行 使用 Apple 的编译器。从技术上讲,Apple 的可空性只是 Objective-C(并扩展为 Objective-C++)标准的一部分,因此是依赖于编译器的 C++ 的非标准扩展(因此其开头的下划线是为特定于编译器的关键字保留)。

NB - 出于性能原因,大多数 C++ 编译器只是将引用实现为指针之上的语法糖,因此在实践中,您可以做一些邪恶的事情,例如

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

他们不会知道你刚刚做了一个 nullptr 引用,但那属于 "undefined" 行为,因此是错误的代码。但是,我不知道目前是否有任何 Objective-C++ 编译器分析 C++ 引用的可空性。快速测试表明 Apple 至少没有。也不确定静态分析器是否捕获它。

PS - 如果你试图编译上面的代码,你应该得到关于在非指针类型。