Програмісти на C ++ не шукають специфікацій виключень. Вони шукають гарантії виключення.
Припустимо, фрагмент коду кинув виняток. Які припущення може зробити програміст, що все ще буде дійсним? Що з написаного коду, що гарантує код після виключення?
Або можливо, що певний фрагмент коду може гарантувати ніколи не кидати (тобто нічого, крім того, що процес ОС завершується)?
Слово "відкат" часто зустрічається в дискусіях про винятки. Можливість повернутись до дійсного стану (це явно задокументовано) - приклад гарантії виключення. Якщо не існує гарантії винятку, програма повинна припинятися на місці, оскільки навіть не гарантується, що будь-який код, який вона виконує після цього, буде працювати за призначенням - скажімо, якщо пам'ять пошкодилася, будь-яка подальша операція технічно не визначена.
Різні методи програмування на C ++ пропонують гарантії виключення. RAII (управління ресурсами на основі сфери) забезпечує механізм виконання коду очищення та забезпечення вивільнення ресурсів як у звичайних, так і у виняткових випадках. Створення копії даних перед виконанням модифікацій на об'єктах дозволяють відновити стан цього об’єкта, якщо операція не завершиться. І так далі.
Відповіді на це питання StackOverflow дають уявлення про велику довжину програмістів C ++, щоб зрозуміти всі можливі режими відмов, які можуть трапитися з їх кодом, і намагаються захистити дійсність програмного стану, незважаючи на збої. Лінійний аналіз коду С ++ стає звичною.
Розробляючи C ++ (для виробничого використання), ви не можете дозволити собі заглядати деталі. Крім того, бінарний блоб (не з відкритим кодом) є основою програмістів на C ++. Якщо мені доведеться зателефонувати на якийсь двійковий блоб, а крап не вдасться, то зворотний інжиніринг - це те, що далі робитиме програміст C ++.
Довідка: http://en.cppreference.com/w/cpp/language/exceptions#Exception_safety - див. Розділ Безпека виключень.
C ++ зазнала невдалої спроби впровадження специфікацій виключень. Пізній аналіз іншими мовами говорить про те, що специфікації виключень просто не практичні.
Чому це невдала спроба: суворо застосовувати це, воно повинно бути частиною системи типу. Але це не так. Компілятор не перевіряє специфікацію виключень.
Чому C ++ обрав це, і чому досвід інших мов (Java) доводить, що специфікація виключень є суперечливою: Оскільки ви можете змінити реалізацію функції (наприклад, їй потрібно здійснити виклик до іншої функції, яка може кинути новий вид виняток), суворе застосування специфічних винятків означає, що ви також повинні оновити цю специфікацію. Це розповсюджується - можливо, вам доведеться оновити технічні характеристики винятків для десятків чи сотень функцій для простої зміни. У абстрактних базових класах все погіршується (еквівалент C ++ інтерфейсів). Якщо специфікація винятків застосовується для інтерфейсів, реалізація інтерфейсів забороняється викликати функції, які видають різні типи винятків.
Довідка: http://www.gotw.ca/publications/mill22.htm
Починаючи з C ++ 17, [[nodiscard]]
атрибут можна використовувати для повернення значень функції (див. Https://stackoverflow.com/questions/39327028/can-ac-function-be-declared-such-that-the-return-value -може бути ігнорованим ).
Отже, якщо я вніс зміну коду, і це вводить новий вид відмови (тобто новий тип винятку), чи це невід'ємна зміна? Чи повинно було змусити абонента оновити код або принаймні попередити про зміну?
Якщо ви приймаєте аргументи, що програмісти C ++ шукають гарантії виключення замість специфікацій винятків, то відповідь полягає в тому, що якщо новий вид відмови не порушує жоден виняток, гарантує код, який раніше обіцяв, це не є переломною зміною.