Почему компиляторы не могут обнаружить несоответствие использования noexcept? - PullRequest
2 голосов
/ 05 марта 2020

Ниже приведен код, в котором компиляторы частично обнаруживают несоответствие между объявлением метода (то есть с помощью спецификатора noexcept) и реализацией метода.

Компиляторы выдают предупреждение для метода "bazExcept ()", но не в состоянии сообщить что-либо для "baz ()". Но я ожидаю предупреждения в обоих случаях, потому что "bazSub ()" может выдавать исключение, а "baz ()" явно заявляет, что не выбрасывает исключение.

Это работа в процессе (то есть, более поздние версии компилятора будут подловить этот случай) или что-то, что я неправильно понял при использовании «noexcept»?

// Tested with C++11 & C++17
// Tested with msvc 19, gcc 9 & clang 9
// Tested using https://godbolt.org/

// Specifier 'noexcept(false)' (same as no specifier) i.e. may throw exceptions.
void bar() noexcept(false) {}

// No specifier 'noexcept' means 'noexcept(false)' i.e. may throw exceptions.
void bazSub() { throw 42; }

// Specifier 'noexcept' means 'noexcept(true)' i.e. do not throw exceptions.
// Note: Compilers do not detect the problem i.e. bazSub may throw exception.
void baz() noexcept { bazSub(); }

// Specifier 'noexcept' means 'noexcept(true)' i.e. must not throw exceptions.
// Note: Compilers generate a warning.
void bazExcept() noexcept { throw 42; }

int main() {return 1;}

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 05 марта 2020

Почему компиляторам не удается обнаружить несоответствие использования 'noexcept'?

Поскольку они не обязаны это делать. Компиляторы действуют в соответствии со стандартом.

Черновик C ++, за исключением # spe c -5 :

Всякий раз, когда выдается исключение, и выполняется поиск обработчик встречает самый внешний блок функции со спецификацией не-бросающего исключения, вызывается функция std :: terminate.

За этим следует важное примечание:

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

Компиляторам не разрешено отклонять выбрасывание из Функция noexcept и добавление функции noexcept просто вызывают std::terminate.

...