За исключением деструкторов, функций подкачки, конструкторов перемещения и операторов присваивания перемещения, стандарт помечает функцию noexcept
, только если она имеет контракт шириной , т. Е. Она не имеет предпосылки. Эта перегрузка требует, чтобы аргумент был строкой с нулевым символом в конце, поэтому стандарт не помечает его как noexcept
.
Рациональное указано в N3248 :
Функции, отмеченные noexcept
, трудно проверить
Когда функция помечена noexcept
, становится невозможным отмечать неудачные тесты,
особенно в тестовых драйверах, бросая исключение. Типичным примером будет код
который проверяет предварительные условия при входе в функцию:
T& std::vector<T>::front() noexcept {
assert(!this->empty());
return *this->data();
}
При проверке таких защитных проверок у тест-водителя разумным подходом является
зарегистрировать обработчик assert, который генерирует четко определенное исключение, нарушенное предварительным условием,
который ловит тестовый драйвер, чтобы убедиться, что соответствующие assert
действительно
место.
...
Теперь мы можем утверждать, что вызов функции вне контракта, когда vector
пустое, неопределенное поведение, поэтому мы не должны ожидать никаких гарантий. Проблема в том, что неопределенное поведение задается библиотекой; компилятору этот код
отлично определен и, если assert
выдает исключение, программа должна завершиться
хорошо определенным образом, подрывая тест-водителя.
Обратите внимание, что проблема здесь не в том, что мы используем утверждения для поиска ошибок в наших собственных
реализации библиотеки, а скорее в пользовательском коде, который неправильно вызывает нашу библиотеку.
Если мы удалим возможность проверить эти защитные утверждения, мы можем ошибиться,
и тем самым подвергаем наших пользователей риску совершения гораздо более серьезных ошибок, чем распространение
неожиданное исключение.
Кстати, из-за [res.on.exception.handling] / 5 :
Реализация может усилить спецификацию исключений для невиртуальной функции, добавив спецификацию исключений без выбрасывания.
... libstdc++
и libc++
могут пометить эту перегрузку noexcept
.