Исключение C++, неопределенное поведение и отсутствие исключений

Об этой функции

int test(int a,int b)
{
    return a/b;
}

Если я вызову test(2,1), ничего не произойдет.
Но если я вызову test(2,0), это вызовет неопределенное поведение.
В результате я должен определить его как noexcept?

Кстати, почему std::vector::operator[] не noexcept?


person Caesar    schedule 28.02.2016    source источник
comment
Второй вопрос задается здесь: stackoverflow.com/questions/20517259/   -  person Weak to Enuma Elish    schedule 28.02.2016
comment
@JamesRoot Большое спасибо!   -  person Caesar    schedule 28.02.2016


Ответы (2)


Должен ли я определить его как noexcept?

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

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

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

person Weak to Enuma Elish    schedule 28.02.2016

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

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

Опуская noexcept, допускается возможность предоставления бросающей версии функции, например, в целях отладки. Функцию из категории «не нужно выбрасывать» можно безопасно заменить версией с выдачей во время отладки, а затем использовать версию без выбрасывания в «выпускной» сборке. Такие проверки нежелательны в «выпускной» сборке, потому что они часто отрицательно влияют на показатели производительности программы, а также могут вызывать нежелательные побочные эффекты в некоторых случаях (например, если проверки делают что-то вроде проверки стека вызовов или отслеживания общего использования памяти в сборке). программа).

По этой причине operator[] вместо std::vector не является nothrow — он не указан как генерирующий, но замена его генерирующей версией может быть полезна для целей отладки. Если бы он был указан как nothrow, это уменьшило бы возможности разработчиков по отладке своего кода, использующего стандартную библиотеку, перед выпуском.

person Peter    schedule 28.02.2016