оператор-try-finally:
__try складовою-оператор
Оператор try-finally є розширенням Microsoft для мов C і С ++ і дозволяє цільовим програмам гарантувати виконання коду очищення при перериванні виконання блоку коду. Очищення включає такі завдання, як скасування розподілу пам'яті, закриття файлів і звільнення їх дескрипторів. Оператор try-finally особливо корисний для підпрограм, в яких в декількох місцях виконується перевірка на наявність помилок, здатних викликати передчасне повернення з підпрограми.
Супутню інформацію і приклад коду див. Розділ Оператор try-except. Додаткові відомості про структурованої обробці виключень в загальному см. В розділі Структурна обробка винятків. Додаткові відомості про обробку винятків в керованих додатках см. В розділі Обробка виключень в / clr.
Структурована обробка винятків підтримується в Win32 для вихідних файлів як на C, так і на C ++. Однак вона не призначена спеціально для C ++. Для того щоб ваш код краще переносився, краще використовувати механізм обробки виключень мови C ++. Крім того, цей механізм відрізняється більшою гнучкістю, оскільки може обробляти виключення будь-якого типу. У програмах на мові C ++ рекомендується використовувати механізм обробки виключень C ++ (оператори try, catch і throw).
Складовою оператор після пропозиції __try є захищений розділ. Складовою оператор після пропозиції __finally є обробником завершення. Такий обробник визначає набір дій, які виконуються при виході із захищеного розділу незалежно від того, чи відбувається вихід в результаті виключення (ненормальне завершення) або в результаті стандартної передачі управління далі (нормальне завершення).
Управління досягає оператора __try в процесі звичайного послідовного виконання (передачі управління далі). Якщо елемент керування входить в __try. стає активним відповідний обробник. Якщо потік елементів управління досягає кінця блоку try, виконання триває наступним чином.
Викликається обробник завершення.
Після закінчення роботи обробника завершення виконання триває після оператора __finally. Незалежно від того як завершується захищений розділ (наприклад, оператором goto виходу із захищеного тіла або оператором return), обробник завершення виконується перед (before) виходом потоку елементів управління із захищеного розділу.
Оператор __finally не блокує пошук відповідного обробника винятків.
Якщо виключення виникає в блоці __try. операційна система повинна знайти обробник для виключення, або програма завершиться помилкою. Якщо обробник знайдений, будь-які і всі блоки __finally виконуються і виконання триває в обробнику.
Наприклад, припустимо, ряд викликів функцій пов'язує функцію А з функцією D, як показано на наступному малюнку. Кожна функція має один обробник завершення. Якщо виняток створюється в функції D і обробляється в функції А, обробники завершення викликаються в тому порядку, в якому система звільняє стек: D, C і B.
Порядок виконання обробників завершення
Поведінка оператора try-finally відрізняється від деяких інших мов, які підтримують використання оператора finally. наприклад C #. Один оператор __try може мати або __finally. або __except. але не обидва. Якщо обидва слід використовувати одночасно, оператор try-except повинен включати внутрішньої оператор try-finally. Правила, які визначають час виконання кожного блоку, також різняться.
Ключове слово __leave може використовуватися тільки в захищеному розділі оператора try-finally. Воно призводить до того, що виконання переходить в кінець захищеного розділу. Виконання триває з першого оператора в обробнику завершення.
Оператор goto може також вийти із захищеного розділу, проте в цьому випадку продуктивність знизиться, оскільки буде викликано звільнення стека. Оператор __leave більш ефективний, оскільки не викликає звільнення стека.
Вихід з оператора try-finally за допомогою функції часу виконання longjmp вважається ненормальним завершенням. Перехід до оператора __try неприпустимий, але припустимо вихід з нього. Всі оператори __finally. які активні між відправним пунктом (нормальним завершенням блоку __try) і точкою призначення (блоком __except. обробляють виняток), повинні бути запущені. Це називається "локальної розкручуванням".
Якщо блок try з якої-небудь причини завершується передчасно (включаючи вихід з блоку), система виконує пов'язаний блок finally в рамках звільнення стека. У цих випадках функція AbnormalTermination повертає значення TRUE, якщо викликається з блоку finally; в іншому випадку вона повертає значення FALSE.
Якщо в процесі виконання оператора try-finally процес віддаляється, обробник завершення не викликається.
Завершення блоку, що відноситься тільки до систем Microsoft