Как заставить std::vector's operator[] компилироваться, проверяя границы в DEBUG, но не в RELEASE

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

Вопрос

Я использую Visual Studio 2008.

Я знаю, что std::vector проверяет границы с помощью функции at () и имеет неопределенное поведение, если вы пытаетесь получить доступ к чему-либо, используя оператор [] неправильно (вне диапазона).

Мне любопытно, возможно ли скомпилировать мою программу с проверкой границ.Таким образом, оператор[] будет использовать функцию at() и выдавать std::out_of_range всякий раз, когда что-то выходит за рамки.

Режим выпуска будет скомпилирован без проверки границ для operator[], поэтому производительность не ухудшится.

Я задумался об этом, потому что я переношу приложение, написанное с использованием Borland C ++, в Visual Studio, и в небольшой части кода у меня есть это (с i = 0, j = 1):

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

Размер вектора 'v' равен [0][1] (таким образом, элемент 0 вектора имеет только один элемент).Я знаю, что это неопределенное поведение, но Borland возвращает здесь 0, VS выходит из строя.Сбой мне нравится больше, чем возврат 0, поэтому, если я смогу получить больше "сбоев" из-за генерируемого исключения std::out_of_range, миграция будет завершена быстрее (так что это выявит больше ошибок, которые скрывал Borland).

Это было полезно?

Решение

Visual Studio 2005 и 2008 уже выполняют проверку границ на operator[] по умолчанию в и то, и другое отлаживайте и выпускайте сборки.

Макрос для управления этим поведением является _SECURE_SCL.Установите для него значение 0, чтобы отключить проверку границ.

Их текущий план в VS2010 состоит в том, чтобы отключить проверку границ по умолчанию в сборках release, но сохранить ее включенной в debug.(Макрос также переименовывается в _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));
        }

итак, есть проверка границ для векторного класса.Я не смотрел на другие контейнеры, но я уверен, что у них такой же механизм.

Прямо сейчас у меня нет доступа ни к одному компьютеру с Windows.Но если я посмотрю на реализацию 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); }

Проверка не выполнена, событие, хотя и в режиме отладки.Здесь, в этом коде, маркер _GLIBCXX_DEBUG не проверен.

Взгляните на свою собственную реализацию STL, поставляемую с MSVC, и посмотрите, что сделано.Если в любом случае проверка не будет произведена ...у вас нет выбора, кроме как использовать at()..:-(

C ++ определяет векторный оператор[] как не выбрасывающий исключение ради скорости.

Я бы посоветовал вам протестировать приложение в конфигурации отладки некоторое время, пока вы не обретете уверенность в том, что основные "скрытые" ошибки устранены.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top