Может ли std :: string :: compare (const char *) вызвать исключение? - программирование
Подтвердить что ты не робот

Может ли std :: string :: compare (const char *) вызвать исключение?

Это перегрузка (4) здесь

В разделе "Исключения" перегрузки 2,3,5,6 (которые имеют параметры pos1 и/или pos2) названы как бросающие std::out_of_range.

Перегрузка (4) не имеет параметров "pos", но не помечена как noexcept.

Это до реализации, кидает ли она или нет?

В GCC 7 libstdc++ он вызывает char_traits<char>::length и char_traits<char>::compare. Они, кажется, не в состоянии бросить, но не помечены как noexcept.

4b9b3361

Ответ 1

За исключением деструкторов, функций подкачки, конструкторов перемещения и операторов присваивания перемещения, стандарт помечает функцию как noexcept только если она имеет широкий контракт, т.е. Не имеет предварительных условий. Эта перегрузка требует, чтобы аргумент был строкой с нулевым символом в конце, поэтому стандарт не помечает его как noexcept.

Рациональное указано в N3248:

Функции, отмеченные как noexcept, трудно проверить

Когда функция помечена как noexcept становится невозможным пометить тестовые сбои, особенно в тестовых драйверах, с помощью исключения. Типичным примером может служить код, который проверяет предварительные условия при входе в функцию:

T& std::vector<T>::front() noexcept {
 assert(!this->empty());
 return *this->data();
}

При проверке таких защитных проверок тестовым драйвером разумным подходом является регистрация обработчика утверждений, который выдает четко определенное исключение, нарушенное предварительным условием, которое тестовый драйвер перехватывает, чтобы убедиться, что соответствующее assert действительно существует.

...

Теперь мы можем утверждать, что вызов функции вне контракта, когда vector пуст, является неопределенным поведением, поэтому мы не должны ожидать никаких гарантий. Проблема в том, что неопределенное поведение задается библиотекой; для компилятора этот код прекрасно определен, и, если assert выдает исключение, программа должна завершиться точно определенным образом, нарушая работу тестового драйвера.

Обратите внимание, что проблема здесь не в том, что мы используем утверждения для поиска ошибок в наших собственных реализациях библиотеки, а скорее в пользовательском коде, который неправильно вызывает нашу библиотеку. Если мы уберем возможность проверять эти защитные утверждения, мы можем ошибиться и таким образом подвергнуть наших пользователей риску совершения гораздо более серьезных ошибок, чем распространение неожиданного исключения.