Разыменование простого указателя (T*
) может привести к неопределенному поведению , если не существует допустимого объекта указанного типа, на который указывает указатель,Природа UB заключается в том, что результатом может быть что угодно , включая, помимо прочего, исключение C ++.Можно действительно представить реализацию, которая проверяла бы указатели на доступ и создавала исключение.Тем не менее, я сомневаюсь, что такая реализация C ++ когда-либо будет существовать (если вы можете сэкономить время выполнения, зачем использовать C ++?), И обычное поведение на большинстве платформ состоит в том, чтобы либо запутаться (если выделяется память)к процессу) или сбой .На некоторых платформах существуют способы перехвата таких сбоев (например, Windows Структурные исключения ).
Однако унарный operator*()
может быть перегружен и обычно предназначен для интеллектуальных указателей и итераторов.Такие реализации, безусловно, могут делать все, что хотят их разработчики, включая, помимо прочего, создание исключения.Но опять же из-за накладных расходов во время выполнения обычные реализации интеллектуальных указателей проверяют только в отладочных сборках (обычно с использованием какой-либо формы утверждения), но не в сборках выпуска.(Заметным исключением являются итераторы в недавних реализациях Visual C ++, которые получают достаточно тепла для этого необычного поведения.)
Существует очень сильная традиция в C ++ различать ошибокпрограммист мог предотвратить (например, доступ к массиву вне границ) и ошибок, которые программисты не могли предотвратить (например, обрыв сетевого соединения).Для грубой скорости первые обычно приводят к UB , потому что проверка их каждый раз будет стоить производительности.Программистам следует проверять, где это уместно и необходимо.
Это различие можно увидеть в определении иерархии исключений стандартной библиотеки, которая подразделяется на предотвратимые std::logic_error
и непригодные std::runtime_error
.