Правила обнуляемости для объектов C++ в Objective-C++
(Пожалуйста, отредактируйте этот пост, если я использую неправильные термины C++. Я абсолютный новичок в C++.)
Как обнуляемость Objective-C работает с объектами C++ в классе Objective-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);
Буду ли я получать какие-либо предупреждения от Clang или статического анализатора, если я позвоню GetFoo
константы выглядит?
GetFoo(nil, nil);
2 ответа
Вы выбрали два случая C++, где Nullability не имеет смысла.:-)
Ваш
const FooList
тип без указателя, поэтому никогда не может бытьnullptr
(или жеNULL
на старых компиляторах C++).Ссылки определяются стандартом как никогда
nullptr
или. Что имеет смысл, потому чтоnullptr
это тип указателя, и единственный способ перейти отnullptr
ссылка ссылается на нее, что... ну, никто не знает, что происходит, когда вы разыменовываете нулевой указатель.
Тем не менее, единственный случай, когда вы не указали обнуляемость (const Foo*
в структуре) на самом деле, где это будет действительным.
По крайней мере, если вы работаете на компиляторах Apple. Технически, обнуляемость Apple является лишь частью стандартов Objective-C (и, соответственно, Objective-C++), поэтому это нестандартное расширение для C++, которое зависит от компилятора (отсюда подчеркивание в начале, зарезервированное для ключевых слов, специфичных для компилятора).).
NB. По соображениям производительности большинство компиляторов C++ просто реализуют ссылки как синтаксический сахар поверх указателей, поэтому на практике вы можете сделать что-то плохое, например
Foo* myFoo = nullptr;
Foo& myFooRef = *myFoo;
и они не будут знать, что ты только что сделал nullptr
ссылка, но это подпадает под "неопределенное" поведение и, как таковой, является неправильным кодом. Однако я не знаю, анализирует ли какой-либо компилятор Objective-C++ в настоящее время обнуляемость ссылок C++. Быстрый тест показывает, что Apple по крайней мере не делает. Не уверен, что статический анализатор ловит его тоже.
PS - Если вы попытались скомпилировать приведенный выше код, вы должны получить ошибку об использовании _Nullable
(SIC) на тип без указателя.
Джордан Роуз (из команды Swift в Apple) говорит:
Ссылки не являются указателями, поэтому они не обнуляются. Но ссылки уже могут быть NULL в соответствии со стандартом C++.
Так что вопрос спорный.
Тем не менее, в отношении указателей:
[Обычные указатели по-прежнему обнуляются в C++ и Objective-C++] (но, к сожалению, вокруг шаблонов есть много грубых краев. Обнуляемость ObjC++ не была приоритетом.)