Я схильний додавати багато тверджень до свого коду С ++, щоб полегшити налагодження, не впливаючи на продуктивність збірки випусків. Зараз assert
це чистий макрос С, розроблений без урахування механізмів С ++.
C ++, з іншого боку, визначає std::logic_error
, що призначено для викиду у випадках, коли в логіці програми є помилка (звідси і назва). Кидання екземпляра може бути просто ідеальною, більш альтернативною C ++ assert
.
Проблема полягає в тому, що assert
і abort
як завершити програму відразу без виклику деструкторів, тому пропуск очищення, в той час як кидати виключення вручну додає непотрібні витрати часу виконання. Одним із шляхів цього може бути створення власного макросу твердження SAFE_ASSERT
, який працює так само, як аналог C, але створює виняток у випадку відмови.
Я можу придумати три думки з цієї проблеми:
- Дотримуйтесь твердження C. Оскільки програма припиняється негайно, не має значення, чи правильно розгорнуто зміни. Крім того, використання
#define
s у C ++ так само погано. - Викиньте виняток і впіймайте його в main () . Дозволити коду пропускати деструктори в будь-якому стані програми є поганою практикою, і його слід уникати будь-якою ціною, а також заклики до terminate (). Якщо кидаються винятки, їх потрібно зловити.
- Викиньте виняток і нехай він припинить програму. Виняток із завершенням програми - це нормально, і через
NDEBUG
це це ніколи не відбудеться у збірці релізу. Зловживання непотрібне і відкриває деталі реалізації внутрішнього кодуmain()
.
Чи існує остаточна відповідь на цю проблему? Будь-яке професійне посилання?
Редаговано: Пропуск деструкторів - це, звичайно, не визначена поведінка.
logic_error
це логічна помилка. Помилка в логіці програми називається помилкою. Ви не вирішуєте помилки, кидаючи винятки.