Как я могу избежать использования исключений в C ++? - PullRequest
3 голосов
/ 21 сентября 2009

Какие методы можно использовать, чтобы избежать исключений в C ++, как указано в Руководстве по стилю Google ?

Ответы [ 5 ]

8 голосов
/ 21 сентября 2009
  1. Не бросайте исключения.
  2. Не используйте STL (который сильно зависит от исключений).
  3. Используйте только new(std::nothrow) или переопределите ::operator new, чтобы вернуть 0 при ошибке.

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

3 голосов
/ 21 сентября 2009

Отказ от исключений в вашем собственном коде относительно прост: вы просто не используете оператор throw.

Не выбрасывать исключения из сбоев выделения памяти немного более болезненно: либо вы не используете обычный new (вместо этого используйте new(std::nothrow) или malloc или что-то еще), либо вы используете нестандартную опцию компилятора, чтобы получить его делать что-то нестандартное в случае сбоя (например, немедленно завершить программу или вернуть 0), или вы переопределяете operator new, чтобы сделать что-то нестандартное в случае сбоя.

Если выбранный вами подход заключается в немедленном прекращении работы программы, вы можете реализовать это с помощью set_new_handler(), о котором я забыл, пока litb не напомнил мне.

Это оставляет проблему работы с исключениями, генерируемыми библиотеками C ++, которые вы не поддерживаете. Обычно вам нужно обернуть библиотечные вызовы в оболочку, которая выглядит примерно так:

int DoSomething(int &output, const int input) throw() {
  try {
    output = library_do_something(input);
    return 1;
  } catch (...) {
    return 0;
  }
}

catch (...) перехватывает все возможные исключения C ++ из library_do_something (а также оператор присваивания в output, который здесь не актуален), отбрасывает всю информацию, которую они могли содержать, и затем отображает все эти сбои 0.

Обратите внимание, что этот стиль означает, что вы вообще не можете использовать RAII, даже немного, потому что у вас нет способа сообщить о сбое в конструкторе. Весь смысл RAII состоит в том, что вы получаете все свои ресурсы внутри конструкторов, так что они будут должным образом освобождены деструктором во время распространения исключений. Но приобретение ресурсов - это то, что по сути всегда может потерпеть неудачу. Так что вы не можете сделать это внутри конструктора.

2 голосов
/ 21 сентября 2009

Мне интересно узнать, почему нужно избегать исключений в C ++ и каким механизмом их заменить, чтобы справиться с реальностью неожиданного сбоя, при этом сохраняя приличную структуру.

Конечно, добавление их в существующую кодовую базу, которая не использует семантику типов RAII, чрезвычайно дорого - но если кто-то занимается разработкой «зеленых полей», то какую альтернативу вы бы предложили и как это оправдать, если не использовать высококачественные библиотеки, которые используют исключения или написание собственных исключений без ошибок / без ошибок?

1 голос
/ 21 сентября 2009

Руководство по стилю говорит, что они «не используют исключения», это просто - они не выдают их и не вызывают ничего, что могло бы их выкинуть (например, они использовали бы new(std::nothrow) вместо обычного new, потому что последний выдаст bad_alloc, когда ему не удастся выделить память.

0 голосов
/ 21 сентября 2009

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

Кроме этого, очевидным первым шагом было бы избегать выброса исключений из вашего собственного кода, возможно, с либеральным использованием директивы nothrow , и пытаться избежать выброса исключений из внешнего (стороннего) кода через защитное программирование .

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

В некоторых случаях вы можете использовать версии кода без исключений (например, throwing-new или non-throwing new).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...