C try-except va try-finally

Bayonot try-except odatda bajarilishini to'xtatib qo'yadigan hodisalar ro'y berganda ilovalarga dasturni boshqarish imkonini beruvchi C tiliga Microsoft kengaytmasi hisoblanadi. Bunday hodisalar istisnolar deb ataladi va istisnolar bilan shug'ullanadigan mexanizm tuzilgan istisnolar bilan ishlash deb ataladi. Istisnolar apparat yoki dasturiy ta'minotga asoslangan bo'lishi mumkin. Ilovalar apparat yoki dasturiy ta'minotdagi istisnolardan to'liq tiklana olmasa ham, tizimli istisnolarni boshqarish xato ma'lumotlarini jurnalga kiritish va ko'rsatish imkonini beradi. Muammoni aniqlashga yordam berish uchun ilovaning ichki holatini tuzoqqa tushirish foydalidir. Xususan, takrorlash oson bo'lmagan intervalgacha muammolar uchun foydalidir.

Sintaksis:

try-except-statement:
 __try compound-statement __except ( expression ) compound-statement

Gapdan keyingi qo'shma __try gap himoyalangan bo'limdir. Gapdan keyingi qo'shma __except gap istisno ishlovchi hisoblanadi. Ishlovchi qo'riqlanadigan qismni bajarishda istisno paydo bo'lsa, bajarilishi kerak bo'lgan harakatlar to'plamini belgilaydi. Amalga oshirish quyidagicha davom etadi:

  1. Qo'riqlanadigan qism bajariladi.
  2. Agar qo'riqlanadigan qismni __except bajarishda istisno sodir bo'lmasa, ijro banddan keyingi bayonotda davom etadi.
  3. Agar qo'riqlanadigan qismni bajarish paytida istisno sodir bo'lsa yoki qo'riqlanadigan bo'lim har qanday rejimda chaqirilsa, __except ifoda baholanadi. Qaytarilgan qiymat istisnoning qanday ishlashini aniqlaydi.

Uchta mumkin bo'lgan qiymat mavjud:

  1. EXCEPTION_CONTINUE_SEARCH: Istisno tan olinmadi. Ishlovchi uchun stekni qidirishni davom eting, avval try-except bayonotlarni o'z ichiga olgan, so'ngra keyingi eng yuqori ustunlikka ega ishlov beruvchilar uchun.
  2. EXCEPTION_CONTINUE_EXECUTION: Istisno tan olingan, ammo rad etilgan. Istisno sodir bo'lgan joyda bajarishni davom ettiring.
  3. EXCEPTION_EXECUTE_HANDLER: Istisno tan olingan. Murakkab bayonotni bajarish orqali boshqaruvni istisno ishlovchisiga o'tkazing __except, so'ngra istisno sodir bo'lgan nuqtada bajarishni davom ettiring.

Ifoda C ifodasi sifatida baholanganligi sababli __except, u bitta qiymat, shartli ifoda operatori yoki vergul operatori bilan cheklangan. Agar kengroq ishlov berish talab etilsa, ifoda yuqorida sanab o'tilgan uchta qiymatdan birini qaytaradigan tartibni chaqirishi mumkin.

Eslatma: Strukturaviy istisnolar bilan ishlash C va C++ manba fayllari bilan ishlaydi. Biroq, u C++ uchun maxsus ishlab chiqilmagan. Portativ C++ dasturlari uchun tuzilgan istisnolar bilan ishlash o‘rniga C++ istisnolardan foydalanish kerak. Bundan tashqari, C++ istisnolar bilan ishlash mexanizmi ancha moslashuvchan, chunki u har qanday turdagi istisnolarni boshqarishi mumkin. Qo'shimcha ma'lumot olish uchun C++ til ma'lumotnomasida istisnolardan foydalanish bo'limiga qarang.

Ilovadagi har bir tartib o'zining istisno ishlovchisiga ega bo'lishi mumkin. Ifoda korpus __except doirasida bajariladi. __try U yerda e'lon qilingan har qanday mahalliy o'zgaruvchilarga kirish huquqiga ega.

__leave kalit so'z try-except bayonot blokida amal qiladi. Uning ta'siri blokning __leave oxiriga o'tishdir. try-except Istisno ishlov beruvchisi tugagandan so'ng bajarish davom etadi. Garchi goto bayonot xuddi shu natijaga erishish uchun ishlatilishi mumkin bo'lsada, bayonot stekni ochishga goto olib keladi. Bayonot __leave samaraliroq, chunki u stekni ochishni o'z ichiga olmaydi. Ish vaqti funksiyasidan try-except foydalangan holda bayonotdan chiqish g'ayritabiiy tugatish hisoblanadi. Bayonotga shoshilish qonuniy emas, lekin longjmp bitta bayonotdan sakrash qonuniydir. Agar jarayon bayonotni __try bajarish o'rtasida o'ldirilgan bo'lsa, istisno ishlov beruvchisi chaqirilmaydi.

Misol: Bu yerda istisno ishlov beruvchisi va tugatish ishlovchisi misoli keltirilgan.

puts("hello");
__try {
  puts("in try");
  __try {
     puts("in try");
     RAISE_AN_EXCEPTION();
  } __finally {
     puts("in finally");
  }
} __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) {
  puts("in except");
}
puts("world");

O'ng tomonda izoh qo'shilgan misoldan olingan natija:

Chiqish:

hello
in try             /* fall into try                       */
in try             /* fall into nested try                */
in filter           /* execute filter; returns 1 so accept */
in finally         /* unwind nested finally               */
in except          /* transfer control to selected handler */
world              /* flow out of handler                 */

try-finally

Bayonot try-finally C tilining Microsoft kengaytmasi bo'lib, u ilovalarga kod blokining bajarilishi to'xtatilganda tozalash kodining bajarilishini kafolatlash imkonini beradi. Tozalash xotirani ajratish, fayllarni yopish va fayl tutqichlarini chiqarish kabi vazifalardan iborat. Bayonot try-finally, ayniqsa, tartibdan muddatidan oldin qaytishga olib kelishi mumkin bo'lgan xatolik tekshiriladigan bir necha joylarga ega bo'lgan tartiblar uchun foydalidir.

try-finally-statement:
 __try compound-statement __finally compound-statement

Bo‘lakdan keyingi qo‘shma __try gap qo‘riqlanuvchi qismdir. Gapdan keyingi qo‘shma __finally gap tugatish ishlovchisi hisoblanadi. Ishlovchi qo'riqlanadigan qismdan chiqqanda bajariladigan harakatlar to'plamini belgilaydi. Qo'riqlanadigan qismdan istisno (g'ayritabiiy tugatish) yoki standart pasayish (normal tugatish) bilan chiqishi muhim emas.

Boshqarish __try oddiy ketma-ket bajarish (tushish) orqali bayonotga etadi. Boshqaruv bayonotga kirganda __try, unga bog'langan ishlov beruvchi faollashadi. Amalga oshirish quyidagicha davom etadi:

  1. Qo'riqlanadigan qism bajariladi.
  2. Tugatish ishlov beruvchisi chaqiriladi.
  3. Tugatish ishlov beruvchisi tugagach, bajarilish __finallybayonotdan keyin davom etadi. Qo'riqlanadigan qism qanday tugashidan qat'i nazar (masalan, goto qo'riqlanadigan organdan bayonot orqali yoki returnbayonot orqali), tugatish ishlov beruvchisi boshqaruv oqimi qo'riqlanadigan qismdan chiqib ketishidan oldin bajariladi.

__leave kalit so'z try-finally bayonot blokida amal qiladi. Uning ta'siri blokning __leave oxiriga o'tishdir. try-finally tugatish ishlov beruvchisi darhol bajariladi. Garchi goto bayonot xuddi shu natijaga erishish uchun ishlatilishi mumkin bo'lsada, bayonot stekni ochishga goto olib keladi. Bayonot __leave samaraliroq, chunki u stekni ochishni o'z ichiga olmaydi. Bayonot yoki ish vaqti funksiyasi try-finally yordamida bayonotdan chiqish g'ayritabiiy tugatish hisoblanadi. Bayonotga sakrash qonuniy emas, lekin biridan sakrash qonuniydir. Jo'nash nuqtasi va belgilangan manzil o'rtasida faol bo'lgan barcha bayonotlar ishga tushirilishi kerak. Bu mahalliy dam olish deb ataladi. Agar try-finally bayonot bajarilayotganda jarayon o'chirilgan bo'lsa, tugatish ishlov beruvchisi chaqirilmaydi.