سؤال

ما هي النقاط المهمة حول الاستثناءات المنظمة التي يجب أن يعرفها كل مطور C ++؟

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

المحلول

إنها مكافئة Win32 لإشارات UNIX ، وتتيح لك التقاط استثناءات من وحدة المعالجة المركزية مثل انتهاك الوصول ، والتعليمات غير القانونية ، تقسم على الصفر.

باستخدام خيارات البرمجة المترجم الصحيحة (/eha for Visual C ++) ، تستخدم استثناءات C ++ نفس آلية حيث تعمل المكدس بشكل صحيح لكل من استثناءات C ++ (المستخدم) واستثناءات SEH (OS).

على عكس استثناءات C ++ ، لا يتم كتابة SEH ولكن جميعها تشترك في نفس بنية البيانات التي لها رمز استثناء (السبب) ومعلومات إضافية حول الرمز الذي يخطئه وما هي سجلات وحدة المعالجة المركزية المحتفظ بها في وقت الخطأ. نرى GetExceptionCode و GetExceptionInformation لمزيد من التفاصيل حول هذا.

أيضًا ، لدى SEH التعامل "الأول" ، والذي يسمح لك بتسجيل أو التعامل مع الاستثناء بطريقة أخرى قبل الاسترخاء يدمر جميع المتغيرات المحلية.

نصائح أخرى

لقد واجهت مؤخرًا مشكلة تسببت في SEH بشكل غير مباشر ، وتحديداً بسبب ميزة واحدة من SEH والتي أعتقد أن كل مطور يجب أن يكون على دراية بـ:

عند استخدام SEH ، لا يتم استدعاء المدمرين ، لذلك إذا كان لديك رمز التنظيف في المدمر الخاص بك ، فلن يتم تنظيفه.

كانت مشكلتنا ناتجة عن قسم حاسم تم لفه كائن مع قفل في المنشئ وفتح في المدمر.

كان لدينا حالة من حالة خروج مصلتة ولم نتمكن من معرفة السبب ، وبعد حوالي أسبوع من البحث في الكود والمقالب وتصحيح الأخطاء ، فهمنا أخيرًا أنه كان هناك استثناء تم التعامل معه من قِبل COM والتسبب . لقد قمنا بتغيير علامة تجميع في VS في خصائص المشروع التي تخبرها بتشغيل المدمرين حتى من أجل SEH والتي حلت المشكلة.

لذلك على الرغم من أنك قد لا تستخدم SEH في الكود الخاص بك ، فقد تستخدم مكتبة تقوم (مثل COM) والتي يمكن أن تسبب سلوكًا غير متوقع.

يجب أن يعلموا أنهم ليسوا جزءًا من C ++ القياسي - فهي اختراع Microsoft ويمكن استخدامها بلغات أخرى غير C ++.

دورة تصادم على أعماق معالجة الاستثناءات المنظمة لـ Win32 ™

هذا المقال هو ال إشارة إلى الاستيقاظ مع SEH. بعد 13 عامًا ، لا يزال الأفضل.

هناك موضوع مخصص على MSDN SEH مقابل C ++ الاستثناء معالجة الاختلافات.

بعض الأشياء التي يجب على مطور C ++ معرفة ما إذا كانت SEH تتم مناقشة:

كتابة C/C ++ SEH معالجات الاستثناء:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

هذا هو ليس C ++ معالجة الاستثناء ، هو ملحقات MS محددة لتثبيت inot seh مباشرة. إنه يعمل بشكل مختلف تمامًا عن استثناءات تشغيل C ++ الخاصة بك. تحتاج إلى فهم جيد لـ SEH لاستخدام هذه.

كتابة C/C ++ SEH معالجات الإنهاء:

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

كما هو الحال مع معالج SEH ، لا تخلط بين هذا مع دلالات استثناء C ++. أنت بحاجة إلى فهم جيد لـ SEH.

_set_se_trasnlator: هذه هي الوظيفة التي تترجم استثناءات SEH إلى استثناءات نوع C ++ عند استخدام الاستثناءات غير المتزامنة /eha.

وأخيراً ، الرأي الشخصي: هل يجب على مطور C ++ يعرف SEH؟ بعد الصاعد الأول لك .ecxr ستفهم أنه عندما تصل الضغط إلى استثناءات C ++ ، فإن الوهم مجرد وهم يتم توفيره لراحتك. الشيء الوحيد الذي يحدث هو SEH.

نقطة مهمة هي معرفة متى تستخدم SEH ومتى تستخدم استثناءات C ++ القياسية. أولاً ، اختر نظامًا واحدًا فقط - أنظمة الخلط تميل إلى أن تكون مشكلة ، مما يتطلب فهمًا عميقًا لكلاهما للتنفيذ جيدًا. ثانياً ، على مستوى عالٍ ، لا يقتصر SEH على C ++ ، في حين أن استثناءات C ++ القياسية لا تقتصر على Windows. إذا لم يملي هذا قرارك ، فاختر استثناءات قياسية ما لم تكن كافية (انظر الإجابات الأخرى لمزيد من التفاصيل حول ما يمكن أن يفعله SEH).

اقتباس من وثائق Microsoft (بتاريخ 08/13/2018) يدعم هذا الاستنتاج.

يعد معالجة الاستثناءات المنظمة (SEH) امتدادًا لـ Microsoft إلى C للتعامل مع بعض المواقف الرمز الاستثنائي ، مثل أخطاء الأجهزة ، بأمان. على الرغم من دعم Windows و Microsoft C ++ SEH ، فإننا نوصي باستخدام معالجة استثناء C ++ ISO-Standard لأنه يجعل الكود الخاص بك أكثر محمولة ومرونة. ومع ذلك ، للحفاظ على التعليمات البرمجية الحالية أو لأنواع معينة من البرامج ، قد لا يزال يتعين عليك استخدام SEH.

لماذا يوصي مؤلف التمديد بعدم استخدامه في معظم الحالات؟ من المفترض أن التمديد مكتوب لـ C والسياق الحالي هو C ++. تتشابه اللغات ، لذا فإن تنفيذ SEH إلى C ++ لأن المنفعة الجانبية ربما كان سهلاً بما فيه الكفاية ، على الرغم من أن "أنواع معينة من البرامج" فقط هي التي ستستفيد حقًا. (أو ربما سبب آخر ؛ ربما بدأ النقل قبل توحيد C ++. يتم تلميع التاريخ.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top