Как функции информируют пользователя о том, что он генерирует исключение на основе прототипа функции? - PullRequest
3 голосов
/ 13 февраля 2020

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

Например:

/* AudioStream.h */
class AudioStream
{
   int open(struct stream_settings &settings);
}
/* AudioStream.cpp */
int AudioStream::open(struct stream_settings &settings)
{
    int err;
    err = snd_pcm_open(...);
    if (err < 0)
    {
        /* Throw some exception here */
    }
}

Если последний Продукт попадает в библиотеку с заголовком. Как выяснить, что функция open выдает исключение, и его необходимо поместить в блок try / catch?

Спасибо за все отличные ответы.

Ответы [ 4 ]

2 голосов
/ 13 февраля 2020

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

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

Есть также большой разговор от моего человека Херба Саттера об исключениях.

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

2 голосов
/ 13 февраля 2020

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

1 голос
/ 13 февраля 2020

C ++ имел throw спецификацию , которая устарела с C ++ 11 и может использоваться следующим образом:

void f() throw(int);

, но отсутствие этого спецификатора в прототипе функции НЕ гарантирует эта функция не будет выдавать

Начиная с C ++ 11, существует нет исключений, кроме спецификатора :

void f() noexcept; // the function f() does not throw
void (*fp)() noexcept(false); // fp points to a function that may throw

, но снова

нет, кроме спецификации на функция не является проверкой во время компиляции; это просто метод для программиста сообщить компилятору, должна ли функция генерировать исключения

Приведенные выше примеры кода взяты со связанных страниц, и вы можете прочитать больше об этих спецификаторах.

ОБНОВЛЕНИЕ: Следуя предложению @ FrancoisAndrieux, я хочу добавить, что хотя это не проверка во время компиляции , вы можете проверить во время компиляции, имеет ли функция этот спецификатор или нет, что может помочь вам оптимизировать ваш код

1 голос
/ 13 февраля 2020

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

Таким образом, рекомендуемый способ, вероятно, состоит в добавлении * Спецификатор 1007 * для каждой функции, которая не может выдать.

См. Также https://en.cppreference.com/w/cpp/language/noexcept_spec и Помогает ли добавление `noexcept (false)` коду в любом случае?

...