Ще в школі близько 10 років тому вони вчили вас використовувати специфікатори виключень. Оскільки мій досвід є одним із них, програмістів Torvaldish C, який вперто уникає C ++, якщо не змушений до цього, я стикаюся лише на C ++, і коли я все ще використовую специфікатори виключень, оскільки саме цього мене вчили.
Однак більшість програмістів на C ++, схоже, нахмуриться на специфікаторів виключень. Я читав дебати та аргументи від різних гурусів С ++, як-от ці . Наскільки я розумію, це зводиться до трьох речей:
- Специфікатори винятку використовують систему типів, що не відповідає решті мови ("тіньова система типу").
- Якщо ваша функція за допомогою специфікатора винятків кидає щось інше, крім того, що ви вказали, програма буде припинятися поганими, несподіваними способами.
- Специфікатори винятку будуть видалені в майбутньому стандарті C ++.
Я чогось тут пропускаю чи це всі причини?
Моя власна думка:
Щодо 1): Так що. C ++ - це, мабуть, найбільш непослідовна мова програмування, коли-небудь зроблена, синтаксично. У нас є макроси, goto / мітки, орда (сховище?) Не визначеного / не визначеного / визначеного поведінки поведінки, неправильно визначені цілі типи, всі неявні правила просування типу, ключові слова у спеціальному випадку, наприклад, товариш, авто , реєструвати, явно ... І так далі. Хтось, мабуть, міг би написати кілька товстих книг про все дивне в C / C ++. То чому люди реагують на цю особливу непослідовність, що є незначною вадою порівняно з багатьма іншими набагато небезпечнішими рисами мови?
Щодо 2): Це не моя власна відповідальність? Є так багато інших способів, як я можу написати фатальну помилку на C ++, чому саме цей випадок гірший? Замість того, щоб писати, throw(int)
а потім кидати Crash_t, я можу також стверджувати, що моя функція повертає вказівник на int, потім робить дикий, явний typecast і повертає вказівник на Crash_t. Дух C / C ++ завжди полягав у тому, щоб залишити більшу частину відповідальності на програміста.
А як щодо переваг тоді? Найбільш очевидним є те, що якщо ваша функція намагається явно викинути будь-який тип, крім того, що ви вказали, компілятор видасть вам помилку. Я вважаю, що стандарт щодо цього зрозумілий (?). Помилки трапляються лише тоді, коли ваша функція викликає інші функції, які, у свою чергу, кидають неправильний тип.
Виходячи зі світу детермінованих, вбудованих програм на С, я, безумовно, вважаю за краще точно знати, яка функція кине на мене. Якщо в мові є щось, що це підтверджує, чому б не використати це? Альтернативи, здається, такі:
void func() throw(Egg_t);
і
void func(); // This function throws an Egg_t
Я думаю, є велика ймовірність того, що абонент ігнорує / забуде застосувати пробний лов у другому випадку, рідше в першому випадку.
Як я розумію, якщо будь-яка з цих двох форм вирішить раптово кинути інший виняток, програма вийде з ладу. У першому випадку тому, що не можна кидати інший виняток, у другому - тому, що ніхто не очікував, що він кине іспанську інквізицію_t, і тому цей вираз не потрапляє там, де мав би бути.
У випадку останнього, щоб випадок кращої можливості (...) на найвищому рівні програми насправді не виглядав нічим кращим, ніж програмний збій: "Гей, десь у вашій програмі щось викинуло дивний, незроблений виняток . ". Ви не можете відновити програму, коли ви знаходитесь далеко від місця, де було викинуто виняток, єдине, що ви можете зробити - це вийти з програми.
І з точки зору користувача, вони могли не менше турбуватися, якщо вони отримають злісне поле від ОС, що говорить "Програма припинена. Blablabla за адресою 0x12345" або поле злого повідомлення з вашої програми, що говорить "Невиправлений виняток: myclass. func.something ». Клоп все ще є.
З майбутнім стандартом C ++ у мене не буде іншого варіанту, крім відмови від специфікаторів винятку. Але я б швидше почув якийсь твердий аргумент, чому вони погані, а не "Його Святість заявив це, і тому це так". Можливо, проти них є більше аргументів, ніж тих, що я перелічив, чи, можливо, є їх більше, ніж я усвідомлюю?