سؤال

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

أي اقتراحات حول كيفية تقليل الاستخدامات أو الحد منها أو حتى القضاء عليها assertب ستكون أفضل إجابة واحدة يمكن للمترجم أن يمسك بنا حتى لا يتعين علينا babysit قاعدة التعليمات البرمجية بقدر ما نفعله حاليا.

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

المحلول

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

assert يتم تمكينه فقط في Buildug Builds، لذلك استخدم إصدار الإفراج من مكتبة جهة خارجية. ولكن حقا، يجب ألا ينتقل الأمر إلى كل لحظة.

نصائح أخرى

قد يكون الأمر مفيدا لتحسين مرفق التأكيد المدمج (لتوفير آثار المكدس، مقالب الأساسية، الذي يعرف). في هذه الحالة، إذا كنت تواجه مشاكل في الحصول على مطوريك لمتابعة أي معايير لديك (مثل "بدلا من assert() استعمال SUPER_ASSERT()"أو أيا كان)، يمكنك فقط وضع خاص بك assert.h رأس في المسار التضمين قبل دليل تشغيل برامج التحويل البرمجي.

سوف تضمن إلى حد كبير أن أي شخص يستخدم المعيار assert() سيحصل الماكرو على خطأ مترجم أو احصل على وظائف تأكيدك (اعتمادا على ما لديك assert.h رأس القيام به).

سيعتمد (على الأقل جزئيا) على ما تتغير. على افتراض أنك لا تمانع في طباعة رسالتها العادية، ومعظمها تريد التخلص منها abort(), ، يمكنك التفكير في المغادرة assert() وحده، وبدلا من ذلك تحديد نسختك الخاصة من abort().

من الناحية النظرية، القيام بذلك غير محمول - ولكن في الواقع، abort() هي وظيفة طبيعية إلى حد ما في المكتبة القياسية، وإذا قمت بربطها بدلا من ذلك، فإنك تحصل على سلوكها. في بعض الأحيان (خاصة بعض رابط Microsoft) عليك القيام ببعض العمل للحصول على رابط للتعاون في استبدال بهم abort() مع لك، ولكن نادرا ما يكون صعبا للغاية.

أعتقد أن سؤالك صالح تماما. إذا قمت بتطبيق التعامل مع الأخطاء الخاصة بك، فقد ترغب في:

  1. دائما يؤدي الزناد حتى في إطلاق سراح.
  2. تنفيذ تقارير خطأ أفضل في حالة مشغلات تأكيد. قد ترغب في إرسال تقارير الأخطاء أو الكتابة إلى ملفات السجل.

يقال إنني لا أرى أي حل يعمل دائما.

  • إذا كنت محظوظا، تستخدم مكتبات الطرف الثالث مؤكدا وحدات الماكرو التي يمكنك إعادة تعريف نفسك طالما أن الملف الذي يحدد هذا الماكرو لديه نوع من #pragma once أو #ifndef __HEADERFILE_H__ #define __HEADERFILE_H__ توفير ضد إدراج متعدد. قم بتضمين ملف الرأس بشكل منفصل، وإعادة تعريف تأكيد وأنت جيد.

  • إذا قاموا مباشرة بتضمين assert.h أو كاسيرت، فيمكنك تصحيح الكود فقط أعتقد. قم بإجراء تغييرات رمز الحد الأدنى، واحفظ التغييرات كملفات تصحيح وعند تحديث المكتبة نأمل أن تصحيحات لا تزال تعمل. أضف البقع إلى عنصر تحكم الإصدار.

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

أعتقد أن السؤال صالح.

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

أنا فقط اتصلت به "تأكيد ()" بدلا من "تأكيد" العادي "وتجنب استخدام تأكيد () على الإطلاق.

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

في الرمز الخاص بي، أنا دائما استخدام Assert(), ، الذي يتوسع إلى وظيفتي الخاصة التي تؤدي إلى تأكيد، أو تتوسع ((void)0) لإصدار الإصدار. سوف المحول البرمجي تحويل ((void)0) التعبير إلى أي شيء، لكنه لا يزال يعتبر كتعبير. هكذا

Assert(3 == x);

سوف تتحول إلى

((void)0);

وكانت الفاصلة المنقوطة مكان للذهاب.

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

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

assert() هو عادة #defineد أن تكون ((باطلة) 0) لإصدار رمز الإصدار (#define NDEBUG)، حتى لا يكون هناك لا النفقات العامة على الإطلاق.

عند استخدام إصدار الاختبار، هل يؤدي الأمر إلى إيذاء قدرةك على الاختبار أن تكون واقعية؟

يبدو أنك تفتقد حقيقة أن قانون الجهة الخارجية هو الأرجح مكتوبا تحت افتراض "قياسي" assert سلوك. أي رمز يتوقع أن ينتهي البرنامج في تأكيد فشل. لا يستطيع الرمز الذي يتبع التأكيد عادة ولن يعمل بشكل صحيح إذا تم كسر الحالة المؤكدة. في 99 حالة من أصل 100 لن تعمل على الإطلاق. في 99 حالة من أصل 100 ستحطمها ببساطة، أي البرنامج سوف ينتهي على أي حال.

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

إذا كان شفرة المصدر تحت سيطرتك:

#define NDEBUG
// Before
#include <assert.h>
// Or other header that includes assert.h

أو باستخدام خيارات الرأس أو الترجمة مسبقا لتحديد NDEBUG.

ثنائيات الجزء الثالث، استخدم إصدار الإصدار منهم.

يجد assert في رؤوس المكتبات (على افتراض أنها ملفات حقيقية على نظام الملفات الخاص بك) واستبدلها بشيء غير صالح

// #define assert(condition) ... /* old definition */
#define assert(condition) ((condition) & "PLEASE DO NOT USE ASSERT" = 42)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top