禁用对c ++向量的边界检查

时间:2010-03-05 03:15:54

标签: c++ g++ libstdc++

使用stl :: vector:

vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking

有没有办法禁用边界检查而不必将所有at()重写为[]?我正在使用GNU标准C ++库。

修改:我在怀疑存在瓶颈的区域将at()更改为[],这大大缩短了计算时间。但是,由于我在开发代码和运行实验之间进行迭代,我想在开发过程中启用边界检查,并在运行实验时禁用它。我想安德鲁的建议是最好的解决方案。

8 个答案:

答案 0 :(得分:24)

如果您真的想这样做(至少对于快速和脏的分析比较),如果您没有其他at()

,这将有效
#define at(x) operator[](x)

如果您想保留at()进行开发并在生产中使用operator[],只需将其打包在#ifdef中。

如果您有其他at(),则可以随时修改#include d <vector>个文件。

答案 1 :(得分:15)

没有。 std::vector::at的边界检查由标准指定,并且没有符合标准的C ++实现可能与此不同。

答案 2 :(得分:6)

也许更好的解决方案是使用[]并使用标准库的已检查实现进行调试。

答案 3 :(得分:5)

根据您想要打开/关闭边界检查的注释,您可以使用包装器模板函数:

template <class T>
inline typename T::reference deref(T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

template <class T>
inline typename T::const_reference deref(const T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

您必须修改您的代码才能启用此功能,但是一旦您将其安装到位,您可以根据需要打开或关闭绑定检查。

我承认使用它看起来有点难看:

deref(vec, 10) = ...;

答案 4 :(得分:3)

不是标准方式。您可以关闭编译器中的异常。您可以使用带有-fno-exceptions的gcc执行此操作。

你应该警惕这样做;您的库(包括标准库)可能无法正常关闭异常。检查您的文档以及this one on the gcc mailing list

等主题

答案 5 :(得分:2)

在您自己的命名空间中导出您自己的矢量类,如“uncheckedvector”,并覆盖基矢量类型的at()以使用数组索引。

然后使用“使用uncheckedvector :: vector”将允许您覆盖所有向量的使用。 如果您在任何地方使用完全限定类型,这将无效。

答案 6 :(得分:2)

始终想要检查时,请使用at()。另请注意,这会在出错时抛出异常,因此可能会被恢复。如果你想要更快,未经检查的访问者,请使用[],但是应该彻底测试使用它的算法,因为失败模式更严重(未定义的行为)。

在Linux上使用GCC时,有两种开发模式边界检查[]的方法:

其他一些有趣的讨论:vector::at vs. vector::operator[]

答案 7 :(得分:0)

如果您具有合理一致的访问模式(即/非随机访问),而不是使用at()[],则避免范围检查的一种方法是使用begin()使用迭代器,end()advance()甚至更好,通过使用标准算法。

虽然这不能解决纠正at()进行范围检查的根本问题,但标准库(MSVC)的某些实现已经检查了某些类型的构建的迭代器