2016-02-28 2 views
0

Об этой функцииC++, неопределенное поведение и noexcept

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

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

BTW, почему std :: vector :: operator [] not noexcept?

+0

Второй вопрос задается здесь: http://stackoverflow.com/questions/20517259/why-vector-access-operators-are-not-specified-as-noexcept –

+0

@JamesRoot Спасибо большое! – Caesar

ответ

0

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

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

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

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

0

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

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

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

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

Смежные вопросы