如何使的std :: vector的操作符[]编译做边界在DEBUG检查,但不发布(How to m

2019-06-18 13:12发布

我使用Visual Studio 2008。

我知道,性病::向量有界与于()函数检查,并已未定义行为,如果你尝试使用operator []的错误(超出范围)来访问的东西。

我很好奇,如果有可能编译我的程序与边界检查。 这样,运营商[]将使用在()函数,并抛出一个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仅具有一个元素)。 这是不确定的行为,我知道,但Borland公司将返回0这里,VS崩溃。 我喜欢的崩溃不是返回0更好,所以如果我可以用的std :: out_of_range例外得到更多的“崩溃”被抛出,迁移速度会更快完成(所以它会暴露更多的错误是Borland公司隐藏)。

Answer 1:

Visual Studio 2005和2008年已经做边界检查的operator[]在默认情况下,在这两种调试和发布版本。

控制这种行为的宏_SECURE_SCL 。 将它设置为0禁用边界检查。

在VS2010他们目前的计划是在默认情况下禁用边界检查在发布版本,但将其保留在调试。 (宏也越来越重命名为_ITERATOR_DEBUG_LEVEL 。我不知道是否有它可用任何正式的文件还没有,但它已被提到这里和这里 )



Answer 2:

启用标志_GLIBCXX_DEBUG做边界上STL容器检查,因为这里讨论: http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html



Answer 3:

我问这个太过早,但我无论如何张贴的答案,所以我分享一些知识。

在Visual Studio中实现了STL已经做在调试模式下进行编译时边界检查。 这可以在可见<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));
        }

于是就有了边界检查为Vector类。 我没有看其他容器,但我相信他们有同样的机制。



Answer 4:

我没有获得任何Windows机器现在。 但是,如果我看着相克我的Mac OS X的机器上发表++,从/usr/include/c++/4.0.0/bits/stl_vector.h的STL实现:

  // 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 marcro在这个代码在这里签出。

在与MSVC提供自己的STL实现看看,看看什么做。 如果没有检查在任何情况下peformed ......你没有选择,只能在使用().. :-(



Answer 5:

C ++定义的速度的缘故矢量运算符[]作为不引发异常。

我建议您可以测试调试配置的应用程序一段时间,直到你获得自信是主要的“隐藏”的错误了。



文章来源: How to make std::vector's operator[] compile doing bounds checking in DEBUG but not in RELEASE