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