كيفية جعل مشغل STD :: متجه [] تجميع القيام بعمل حدود التحقق في تصحيح الأخطاء ولكن ليس في الإصدار

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

سؤال

أنا أستخدم Visual Studio 2008.

أنا أدرك أن STD :: Vector لديه تحديد المواطن مع وظيفة AT () ولديك سلوك غير محدد إذا حاولت الوصول إلى شيء باستخدام المشغل [] بشكل غير صحيح (خارج النطاق).

أنا فضولي إذا كان من الممكن ترجمة برنامجي مع تحديد الحدود. وبهذه الطريقة، ستستخدم المشغل [] وظيفة AT () ورمي STD :: Out_Of_Range كلما كان هناك شيء خارج الحدود.

سيتم تجميع وضع الإصدار دون التحقق من الحدود للمشغل []، وبالتالي فإن الأداء لا يتحلل.

جئت إلى التفكير في ذلك لأنني أرجأ تطبيقا مكتوبا باستخدام Borland C ++ إلى Visual Studio وفي جزء صغير من التعليمات البرمجية لدي هذا (مع i = 0، j = 1):

v[i][j]; //v is a std::vector<std::vector<int> >

حجم المتجه "V" هو [0] [1] (لذلك عنصر 0 من المتجه لديه عنصر واحد فقط). هذا سلوك غير محدد، وأنا أعلم، لكن بورلاند يعود 0 هنا، مقابل تعطل. أحب التعطل بشكل أفضل من العودة 0، لذلك إذا كان بإمكاني الحصول على المزيد من "تعطل" من قبل STD :: Out_Of_Range الاستثناء، فسيتم إكمال الترحيل بشكل أسرع (لذلك سيكشف المزيد من الأخطاء التي كانت بورلاند تختبئ).

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

المحلول

Visual Studio 2005 و 2008 بالفعل قيد التحقق من operator[] بشكل افتراضي، في على حد سواء تصحيح وإصدار يبني.

الماكرو للتحكم في هذا السلوك هو _SECURE_SCL. وبعد اضبطه على 0 لتعطيل التحقق من الحدود.

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

نصائح أخرى

قم بتمكين العلم _glibcxx_debug لإجراء التحقق من حاويات STL، كما تمت مناقشته هنا:http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

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

تقوم STL المطبقة في Visual Studio بإجراء التحقق من تحديد المرتبات عند التجميع في وضع التصحيح. هذا يمكن أن ينظر إليه في <vector> رأس:

reference operator[](size_type _Pos)
        {   // subscript mutable sequence

 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));
        }

لذلك هناك حدود التحقق من فئة المتجه. لم أنظر إلى حاويات أخرى، لكنني واثق من أن لديهم نفس الآلية.

ليس لدي حق الوصول إلى أي جهاز ويندوز الآن. ولكن إذا نظرت إلى تطبيق STL الذي تم تسليمه باستخدام G ++ على جهاز Mac OS X، من /usr/include/c++/4.0.0/bits/stl_vector.h:

  // element access
  /**
   *  @brief  Subscript access to the data contained in the %vector.
   *  @param n The index of the element for which data should be
   *  accessed.
   *  @return  Read/write reference to data.
   *
   *  This operator allows for easy, array-style, data access.
   *  Note that data access with this operator is unchecked and
   *  out_of_range lookups are not defined. (For checked lookups
   *  see at().)
   */
  reference
  operator[](size_type __n)
  { return *(begin() + __n); }

لا تحقق إجراء، والحدث على الرغم من وضع تصحيح الأخطاء. لا يتم فحص NO _GLIBCXX_DEBUG MARCRO هنا في هذا الرمز.

إلقاء نظرة على تنفيذ STL الخاص بك تسليمها مع MSVC ومعرفة ما يتم. إذا لم يكن هناك فحص محدد في أي حال ... ليس لديك خيار سوى استخدام () .. :-(

يحدد C ++ مشغل Vector [] كما لا يرمي استثناء من أجل السرعة.

أنصحك باختبار الطلب في تكوين تصحيح لفترة من الوقت حتى اكتسب الثقة في أن الأخطاء "المخفية" الرئيسية ذهبت.

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