ما هي أفضل طريقة تنفيذ التأكيد على التدقيق في C++?

StackOverflow https://stackoverflow.com/questions/179723

سؤال

أقصد, ماذا يجب أن أفعل أن يكون مفيدا التأكيدات في قانون بلدي ؟

MFC سهلة جدا, أنا فقط استخدام تأكيد(شيء).

ما هو غير MFC الطريقة ؟

تحرير: هل من الممكن أن تتوقف عن تأكيد كسر في التأكيد.ج بدلا من الملف الذي يسمى تأكيد()?

تحرير: ما هو الفرق بين <assert.h> & <cassert>?

الإجابة المقبولة: كميات كبيرة من الأجوبة في هذا المنصب, أتمنى أن تقبل أكثر من إجابة واحدة (أو شخص ما من شأنه الجمع بين كل منهم).لذا أجب يحصل منح فيروتشيو (على الإجابة الأولى).

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

المحلول

#include <cassert>

assert(something);

و وقت التحويل البرمجي فحص دفعة ثابتة تؤكد هي مفيدة جدا:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);  // compile fails if ints aren't 32-bit

نصائح أخرى

ذلك يعتمد على ما إذا كان أو لا كنت تبحث عن شيء يعمل خارج Visual C++.ذلك يعتمد أيضا على نوع من التأكيد كنت تبحث عن.

هناك بضعة أنواع من التأكيدات:

  1. المعالج
    هذه التأكيدات تتم باستخدام التوجيه المعالج #error
    المعالج تأكيدات فقط تقييمها من خلال تجهيزها المرحلة ، وبالتالي فهي ليست مفيدة في أشياء مثل قوالب.

  2. تنفيذ الوقت
    هذه التأكيدات تتم باستخدام assert() وظيفة محددة في <cassert>
    تنفيذ الوقت تأكيدات فقط تقييمها في وقت التشغيل.وكما BoltBait أشار يتم تجميعها في إذا NDEBUG ماكرو تم تعريفها.

  3. ثابت
    هذه التأكيدات فعلت كما قلت ، باستخدام ASSERT() ماكرو, ولكن فقط إذا كنت تقوم باستخدام MFC.أنا لا أعرف طريقة أخرى للقيام ثابت التأكيدات التي هي جزء من C/C++ القياسية ، ومع ذلك ، فإن تعزيز تقدم مكتبة حل آخر: static_assert.
    على static_assert وظيفة من دفعة المكتبة هو شيء التي سوف تضاف في C++0x القياسية.

كما تحذير إضافية ، assert() وظيفة فيروتشيو اقترح لا تملك نفس السلوك كما MFC ASSERT() الماكرو.الأول هو تنفيذ الوقت التأكيد ، بينما هو ثابت التأكيد.

آمل أن يساعد هذا!

تأكيد هو (عادة) التصحيح فقط

المشكلة مع "تأكيد" هو أنه عادة ما يكون في التصحيح الثنائيات, و أن بعض المطورين استخدامها كما إذا كان رمز لا يزال في الإنتاج.

هذا ليس شرا في حد ذاته ، كما رمز المفترض أن يكون اختباره بشكل مكثف ، وبالتالي ، فإن الخلل إنتاج تأكيد سيكون بالتأكيد اكتشاف و إزالة.

ولكن في بعض الأحيان (أكثر من مرة؟), الاختبارات ليست مكثفة كما تريد.أنا لن أتكلم عن الوظيفة القديمة حيث كان علينا أن قانون حتى اللحظة الأخيرة (لا يسأل...أحيانا المديرين فقط...مهم...)...ما هو الغرض من تأكيد إضافة إلى التعليمات البرمجية التي سيتم تجميعها وتسليمها في بيان الثنائية إلى العميل القادم دقيقة ؟

يؤكدون في (بعض) الحياة الحقيقية التطبيقات

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

تؤكد كل كشف و معالجة الخطأ فقط على بناء التصحيح.

لذلك أضفنا بدلا XXX_ASSERT الكلي, فضلا عن XXX_RAISE_ERROR الماكرو.

على XXX_ASSERT الكلي سوف تفعل الشيء نفسه كما تؤكد ماكرو, ولكن سيكون بنيت على حد سواء في التصحيح و في الافراج عنهم.سلوكها (كتابة سجل فتح messagebox, لا تفعل شيئا, الخ.) يمكن السيطرة عليها من قبل .INI ثم ، فإنه إحباط/الخروج من التطبيق.

تم استخدام هذا:

bool doSomething(MyObject * p)
{
   // If p is NULL, then the app will abort/exit
   XXX_ASSERT((p != NULL), "Hey ! p is NULL !") ;

   // etc.
}

XXX_RAISE_ERROR الماكرو فقط "سجل" الخطأ ولكن لا نحاول التعامل معها.هذا يعني أنه يمكن تسجيل الرسالة في ملف أو فتح MessageBox مع الرسالة ، و زر إلى آخر لإطلاق تصحيح الدورة (كما في .INI ملف التكوين).تم استخدام هذا:

bool doSomething(MyObject * p)
{
   if(p == NULL)
   {
      // First, XXX_RAISE_ERROR will alert the user as configured in the INI file
      // perhaps even offering to open a debug session
      XXX_RAISE_ERROR("Hey ! p is NULL !") ;
      // here, you can handle the error as you wish
      // Than means allocating p, or throwing an exception, or
      // returning false, etc.
      // Whereas the XXX_ASSERT could simply crash.
   }

   // etc.
}

سنة واحدة بعد دخولها في يبس ، فقط XXX_RAISE_ERROR يتم استخدامه.بالطبع, لا يمكن أن تستخدم في الوقت الحرج أجزاء من التطبيق (لدينا XXX_RAISE_ERROR_DBG) ، في كل مكان آخر ، هو جيد.والحقائق التي يمكن للمرء أن استخدام ما يفضل معالجة الخطأ, و التي يمكن تفعيلها ، إما على المطور الكمبيوتر ، أو اختبار ، أو حتى المستخدم هو مفيد جدا.

للإجابة على السؤال في الثانية "تحرير":

< التأكيد.h> هو رأس C

< cassert> هو C++ القياسية مكتبة رأس ...عادة ما تشمل < التأكيد.h>

لكسر داخل ملف يسمى تأكيد ، يمكنك استخدام ماكرو مخصصة أن يطرح استثناء أو المكالمات __debugbreak:

#define MYASSERT(EXPR, MSG) if (!(EXPR)) throw MSG;

أو:

#define MYASSERT(EXPR) if (!(EXPR)) __debugbreak();

الأساسية تأكيد الاستخدام

#include <cassert>

/* Some code later */
assert( true );

أفضل الممارسات الملاحظات

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

إذا كان لديك حالة حيث كنت ترغب في التأكيد على أن ضرب دائما ، يمكنك تمرير كاذبة إلى ذلك.على سبيل المثال:

switch ( someVal ):
{
case 0:
case 1:
  break;
default:
  assert( false ); /* should never happen */
}

ومن الممكن أيضا لتمرير رسالة من خلال التأكيد على:

assert( !"This assert will always hit." );

ناضجة codebases في كثير من الأحيان تمديد تأكيد وظيفة.بعض الامتدادات الشائعة تشمل:

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

مايكروسوفت محددة CRT يؤكد

#include <crtdbg.h>
#include <sstream>
...
// displays nondescript message box when x <= 42
_ASSERT(x > 42);
// displays message box with "x > 42" message when x <= 42
_ASSERTE(x > 42);
// displays message box with computed message "x is ...!" when x <= 42
_ASSERT_EXPR(
   x > 42, (std::stringstream() << L"x is " << x << L"!").str().c_str());

هناك أكثر تقدما مكتبة مفتوحة المصدر تسمى ModAssert ، وقد التأكيدات التي تعمل على كل من Visual C++ و دول مجلس التعاون الخليجي.وربما أيضا على المجمعين لا نعرف على وجه اليقين.يستغرق بعض الوقت لمعرفة ذلك ، ولكن إذا كنت تريد جيدة التأكيدات التي لا تعتمد على MFC, انظروا إلى هؤلاء.انها في http://sourceforge.net/projects/modassert/

استخدام التحسس إلى فتحه في visual studio (انقر على الحق)

// cassert standard header
#include <yvals.h>
#include <assert.h>

yvals.ح هو ويندوز الأشياء.بقدر ما تؤكد() نفسها هي المعنية ، طريقتين إدراجه متطابقة.انها ممارسة جيدة لاستخدام <cxxx> لأنه في كثير من الأحيان أنها ليست بهذه البساطة (مساحة التغليف و ربما غيرها من السحر)

هذه فواصل في المتصل الموقع بالنسبة لي...

هنا المادة شرح لماذا كنت لا تريد أن تكتب هذا الماكرو نفسك.

هنا هو بلدي أحدث التكرار من التأكيد منشأة في C++: http://pempek.net/articles/2013/11/17/cross-platform-cpp-assertion-library/

انها قطرة في 2 ملفات lib يمكنك بسهولة إضافة إلى المشروع الخاص بك.

إلى إجابة السائل هو السؤال الثالث:السبب الأول نستخدم "cassert" بدلا من "تأكيد.ح" لأنه في حالة C++, هناك بدل ينبغي أن برنامج التحويل البرمجي C++ قد لا تخزين وظيفة الوصف في ملفات التعليمات البرمجية ، ولكن في dll أو في المجمع نفسه.والثاني هو أنه قد يكون هناك تغييرات طفيفة على وظائف من أجل تيسير الاختلافات بين C و C++ ، سواء في الحاضر أو في المستقبل.لأن تأكيد.ح ج مكتبة تفضيل استخدام "cassert" بينما في C++.

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