سؤال

أنا أعمل على ترقية تطبيق Visual C++ إلى دول مجلس التعاون الخليجي (بناء على mingw لينكس).

القائمة رمز يستخدم __try { ... } __except(1) { ... } الكتل في عدد قليل من الأماكن بحيث لا شيء تقريبا (قصيرة ربما من نوع الذاكرة الأخطاء؟) من شأنه أن يجعل خروج البرنامج دون أن تفعل الحد الأدنى من بعض الأشجار.

ما هي الخيارات من أجل القيام بشيء مماثل مع دول مجلس التعاون الخليجي ؟

تحرير:شكرا على المؤشر /إيه الخيارات في Visual Studio, ما أريده الآن هو بعض الأمثلة على كيفية التعامل مع إشارات على لينكس.لقد وجدت هذه الرسالة من عام 2002.

ما إشارات أخرى إلى جانب SIGFPE و SIGSEVG يجب أن احترس ؟ (في الغالب رعاية عن تلك التي قد تثار من لي تفعل شيئا خاطئا)

فضله المعلومات:أريد بلدي التطبيق لتكون قادرة على الذات تسجيل العديد من حالات الخطأ ممكن قبل خروجها.

ما إشارات قد فهمت و التي تكون عادة من المستحيل تسجيل رسالة خطأ بعد ؟ (من الذاكرة ، ماذا بعد؟)

كيف يمكنني التعامل مع الاستثناءات و (الأهم) إشارات في المحمولة الطريقة التي رمز على الأقل تعمل على لينكس و مينغو.#ifdef هو موافق.

السبب في أنني لا يكون مجرد التفاف عملية سجلات الفشل هو أن الأداء أسباب حفظ كتابة بعض البيانات إلى القرص حتى آخر لحظة, حتى إذا كان هناك شيء يذهب على نحو خاطئ أنا تريد أن تجعل كل شيء ممكن محاولات لكتابة البيانات قبل أن تخرج.

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

المحلول

محاولة { xxx } catch(...) { xxx } سيكون أكثر المحمولة ولكن قد لا يمسك بقدر.ذلك يعتمد على مترجم إعدادات والبيئات.

استخدام الافتراضي VC++ إعدادات غير متزامن (SEH) الأخطاء لا يتم تسليم إلى C++ ايه البنى التحتية ؛ للقبض عليهم تحتاج إلى استخدام سيه معالجات (__try/__إلا) بدلا من ذلك.VC++ يسمح لك الطريق سيه الأخطاء من خلال C++ معالجة الأخطاء التي يسمح الصيد(...) إلى فخ سيه الأخطاء ؛ هذا يتضمن أخطاء الذاكرة مثل مؤشر فارغة dereferences. التفاصيل.

على لينكس ، ومع ذلك ، فإن العديد من الأخطاء التي يستخدم Windows سيه هي أوضح من خلال الإشارات.هذه ليست اشتعلت من أي وقت مضى من قبل حاول/catch;التعامل معها تحتاج إشارة معالج.

نصائح أخرى

لماذا لا تستخدم C++ القياسية الاستثناءات بدلا من MSFT الملكية التمديد ؟ C++ استثناء التعامل مع مفهوم.

struct my_exception_type : public logic_error {
    my_exception_type(char const* msg) : logic_error(msg) { }
};

try {
    throw my_exception_type("An error occurred");
} catch (my_exception_type& ex) {
    cerr << ex.what << endl;
}

C++ أيضا "جامعا" شرط لذلك إذا كنت ترغب في تسجيل استثناءات يمكنك استخدام المجمع التالية:

try {
    // …
}
catch (...) {
}

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

لقابلية شيء واحد في محاولة يستخدم محاولة اللحاق كتل معظم الفانيليا الاستثناءات ثم تعيين إنهاء معالج (set_terminate_handler) أن يكون الحد الأدنى هوك المتاحة كارثية الخروج من الظروف.يمكنك أيضا محاولة إضافة شيء مثل atexit أو on_exit معالج.الخاص بك بيئة التنفيذ قد تكون غريبة أو الفاسدة عند إدخال هذه الوظائف ، بالطبع ، لذا كن حذرا كم كنت تفترض عاقل البيئة.

أخيرا, عند استخدام العادية محاولة اللحاق أزواج يمكنك أن تنظر في استخدام وظيفة محاولة كتل بدلا من فتح كتلة المحاولة في جسم الدالة:

int foo(int x) try {
  // body of foo
} catch (...) {
   // be careful what's done here!
}

أنهم غير معروف نسبيا قطعة من C++ و قد تكون في بعض الحالات تقدم الانتعاش حتى في حال الجزئي (صغيرة الحجم) كومة الفساد.

أخيرا, نعم, ربما كنت سوف ترغب في التحقيق الذي إشارات يمكنك continuably التعامل مع الخاص بك أو ربما إحباط, و إذا كنت تريد أقل التعامل مع آليات ، قد تفكر في استدعاء أي رمي النسخة الجديدة من المشغل ، وتجميع أن لا تولد النقطة العائمة الاستثناءات إذا لزم الأمر (يمكنك دائما التحقق من isnan(.), isfinite(.), على FP نتائج لحماية نفسك).

على أن ملاحظة أخيرة, كن حذرا:لقد لاحظ أن النقطة العائمة نتيجة تصنيف الوظائف يمكن أن يكون في رؤوس مختلفة تحت لينكس و ويندوز...لذلك قد تضطر إلى conditionalize هذه وتشمل.

إذا كنت تشعر خبيثة ، وكتابة كل شيء باستخدام setjmp و longjmp (هذه مزحة...).

اصطياد C++ مع استثناءات catch(...) بالفعل يضعك في منطقة الشفق.

في محاولة للقبض على أخطاء لم يدرك من قبل catch(...) يضعك داخل undefined السلوك.لا رمز C++ مضمون العمل.الحد الأدنى الخاص بك تسجيل رمز قد تسبب الصاروخ لإطلاق بدلا من ذلك.

توصيتي هي أن لا تحاول حتى catch(...).إلا قبض الاستثناءات التي يمكنك مجد وأمان تسجيل الدخول والسماح نظام التشغيل التعامل مع بقية إن وجدت.

بعد الوفاة التصحيح يحصل القبيح إذا كان لديك خطأ معالجة رمز الفشل على رأس الجذري.

طريقة واحدة سهلة الاستخدام والمحمولة بالكاد استخدام أي موارد للقبض فارغة الطبقات.أعرف أن هذا قد يبدو غريبا في البداية ، ولكن يمكن أن تكون مفيدة جدا.

هنا مثال عن سؤال آخر أن ينطبق على سؤالك أيضا: الرابط

أيضا, يمكن أن يكون لديك أكثر من 1 الصيد:

try
{
   /* code that may throw exceptions */
}
catch (Error1 e1)
{
   /* code if Error1 is thrown */
}
catch (Error2 e2)
{
   /* code if Error2 is thrown */
}
catch (...)
{
   /* any exception that was not expected will be caught here */
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top