سؤال

توقعت A::~A() ليتم استدعاؤها في هذا البرنامج، ولكنها ليست:

#include <iostream>

struct A {
  ~A() { std::cout << "~A()" << std::endl; }
};

void f() {
  A a;
  throw "spam";
}

int main() { f(); }

ومع ذلك، إذا قمت بتغيير السطر الأخير إلى

int main() try { f(); } catch (...) { throw; }

ثم A::~A() يكون مُسَمًّى.

أقوم بالتجميع باستخدام "Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86" من Visual Studio 2005.سطر الأوامر هو cl /EHa my.cpp.

هل المترجم صحيح كالمعتاد؟ماذا يقول المعيار في هذا الشأن؟

هل كانت مفيدة؟

المحلول

لا يتم استدعاء destructor لإنهاء () لاستثناء غير معالج يسمى قبل ان يحصل على المساس بها المكدس.

والتفاصيل المحددة ما تقول المواصفات C ++ هو خارج من معرفتي، ولكن أثر التصحيح مع جدب وز ++ يبدو أن يتحمل ذلك.

ووفقا لمشروع rel="noreferrer"> قسم معيار

9 If no matching handler is found in a program, the function terminate()
  (_except.terminate_)  is  called.  Whether or not the stack is unwound
  before calling terminate() is implementation-defined.

نصائح أخرى

وC ++ دول مواصفات اللغة: وتسمى هذه العملية من استدعاء تالفة لكائنات آلية شيدت على الطريق من كتلة المحاولة إلى التعبير عن رمي "كومة الفك." كود الأصلي لا يحتوي على كتلة المحاولة، وهذا هو السبب لا يحدث تكدس الفك.

وأنا افترض أيضا أن المترجم لا تولد القوانين المتعلقة "أ" كما انها ليست المشار إليها ولكن لا يزال، انها ليست السلوك الصحيح كما المدمر لا شيء لديها ليتم تنفيذها.

وهكذا، حاولت في VS2008 / vc9 (+ SP1)، تصحيح والإصدار و~ ويسمى بعد يتم طرح استثناء، والخروج من و () - وهذا هو السلوك الصحيح، إذا أنا الصحيح

والآن أنا حاولت فقط مع VS2005 / VC8 (+ SP1) وانها نفس السلوك.

واعتدت نقاط التوقف للتأكد. أنا فقط التحقق مع وحدة التحكم ولدي رسالة "~ A" للغاية. ربما فعلت ذلك في مكان خطأ آخر؟

آسف ليس لدي نسخة من المعيار معي.
أود بالتأكيد الحصول على إجابة محددة لهذا السؤال، لذا يرغب شخص لديه نسخة من المعيار في مشاركة السورة والآية حول ما يحدث:

من وجهة نظري إنهاء يسمى فقط IF:

  • لا يمكن لآلية معالجة الاستثناء العثور على معالج للاستثناء المطروح.
    فيما يلي حالات أكثر تحديدًا لهذا:
    • أثناء تفكيك المكدس، يفلت استثناء من أداة إتلاف.
    • تعبير تم طرحه، استثناء يهرب من المنشئ.
    • استثناء يهرب من المنشئ/المدمر للثابت غير المحلي (أي العالمي)
    • هناك استثناء يهرب من دالة مسجلة في atexit().
    • استثناء يهرب الرئيسي ()
  • محاولة إعادة طرح استثناء في حالة عدم نشر أي استثناء حاليًا.
  • استثناء غير متوقع يهرب من دالة ذات محددات الاستثناء (عبر غير متوقع)

وهذا السؤال هو سهل جوجل حتى أشارك ضعي هنا.

تأكد تطعن اكسيبشن لا عبر الحدود extern "C" أو استخدام MSVC خيار / الصحة والسلامة (تمكين exeptions C ++ = نعم مع وظائف خارجي C (/ الصحة والسلامة))

في المثال الثاني، ويسمى dtor عندما يترك المحاولة {} كتلة.

في المثال الأول، ويسمى dtor كما إيقاف البرنامج عن منصبه بعد ترك الوظيفة الرئيسية () --- التي قد بالفعل تم تدمير الوقت cout.

scroll top