Open klappdev opened 2 years ago
Как замена указателям в С++, имеются ссылки, умные указатели.
Это не замена указателям. В современном С++ это всё разные семантики:
Поэтому потенциальный std::nullable уже есть в языке и называется T*, а std::non_null называется T&
P.S. not_null\<T> это T, nullable\<T> это optional\<T> в более общем случае
Эта проблема на самом деле никак не решается таким методом. Потому что кроме доступа по null указателю, что в общем тиривиальная проблема и быстро находится, реальные неприятности как правило поджидают вот в таких случаях.
int* p;
...
*p = 1;
int *p = new int;
delete p;
...
delete p;
#include <thread>
int main(int argc, const char** argv) {
int *p = new int;
std::thread t0( [p] { *p = 1; } );
std::thread t1( [p] { *p = 2; } );
std::thread t2( [p] { *p = 3 ;} );
delete p;
}
void foo(int* p)
{
if(nullptr != p)
delete p;
}
int main(int argc, const char** argv)
{
int i = 1;
foo(&i);
return 0;
}
Это все никак не решить без статического анализа и рантайм анализа либо дополнительной программми типа СppCheck, Valgrind и т.п. или внесением этих интсрументов в компилятор и среду, по типу Rust.
Умные указатели и стратегия подсчета ссылок уже давно решает часть проблем, но далеко не все. Монады типа std::optional тоже не панация.
Есть у меня идейка, займусь статическим анализом и жёстким и гарантиями на владение
Неотъемлемой частью языка являются указатели. Использование указателей несет некоторые проблемы, в частности: разименование нулевого указателя, работа с нулевым указателями ссылающиеся на поля объекта, и т.д. Как результат имеем segmentation fault, и долгие часы дебага.
Поэтому всегда нужно проверять, является указатель нулевым или нет.
Часто программисты из-за невнимательности или сложной логики кода, могут не все случаи проверить валидности указателей. Как замена указателям в С++, имеются ссылки, умные указатели. Но иногда без указателей не обойтись, например использование С-библиотек, new/delete и т.д.
В Clang попытались решить проблему с указателями, добавив ключевые слова _Nonnull, _Nullable. Атрибуты nullability позволяют статическому анализатору подсказывать, где указатель используется некорректно.
Но что если в проекте не используется статический анализатор кода, или Clang компилятор. То потенциальные ошибки останутся в коде. Что не очень хорошо.
Еще одним решение является реализовать оберточки над указателя - non_null, nullable. Если указатель, в какой-то момент не валидный, то можно бросить исключения. И в нас уже есть замечательная библиотека gsl.
Но почему в библитеке нет gsl::nullable. И еще как минус нельзя расширить обработчик ошибок. Например, если в проекте используется Java/C++, то хотелось кидать java-исключения с нативным стектрейсом. https://github.com/klappdev/firearrow/blob/master/app/src/main/cpp/util/nullability/NonNull.hpp https://github.com/klappdev/firearrow/blob/master/app/src/main/cpp/util/nullability/Nullable.hpp
Предлагаю добавить два класса в стандартную библиотеку - std::non_null<T>, std::nullable<T>. Если указатель, в какой-то момент не валидный, то можно бросить исключения.
Также добавить функцию std::set_nullability(). Для того, чтобы можно переопределить дефолтное поведения. По аналогии с функцией - std::terminate.
Очень хочется видеть подобные оберточки в С++.
Полезные ссылки: