编程时 C++11 std::array
的优点已由专家解释,但我想从编译器那里得到一件事。能够在编译使用 []
的代码时使用 .at()
时默认打开范围检查。
它可能有助于检查范围违规,尤其是对于多维数组,因为在这种情况下,范围违规导致段错误的可能性较小(因为您通常在内部数组周围拥有内存,所以 [5000][-123]
仍可能指向您拥有的内存)。
所以我想知道是否有一个开关可以编译成检查范围的机器代码:
const uint32_t dim1=10*1000,dim2=3;
std::array<std::array<int, dim2>, dim1> test_2Darray;
int undefined_value=test_2Darray[dim2-1][dim1-1];
std::cout<<"ouch ("<<undefined_value<<")"<<std::endl;
int ok_value=test_2Darray[dim1-1][dim2-1];
std::cout<<"OK ("<<ok_value<<")"<<std::endl;
// test_2Darray.at(dim2-1).at(dim1-1); -->terminate called after throwing an instance of 'std::out_of_range'
// what(): array::at
如果你问我为什么不切换到 .at()
- 我可能需要性能,而且我已经编写了很多带有 []
的代码而且我还不够聪明,无法替换 1D 更不用说 2D 阵列了。
我使用 GCC 4.6
最佳答案
gcc 4.6自带的array好像还没有 Debug模式。可以理解,因为 C++11 支持仍处于试验阶段。
有一个标志_GLIBCXX_DEBUG
,通常用于打开 Debug模式。如果您查看/usr/include/c++/4.6/debug/vector:313,您会看到 operator[]
具有:
__glibcxx_check_subscript(__n);
现在,这可能是 super 邪恶的(我的意思是真的邪恶)但看起来我们可以有条件地将它添加到数组中。将/usr/include/c++/4.6/array 的第 148-154 行更改为:
reference
operator[](size_type __n)
{ return _M_instance[__n]; }
const_reference
operator[](size_type __n) const
{ return _M_instance[__n]; }
到:
reference
operator[](size_type __n)
{
#ifdef _GLIBCXX_DEBUG
__glibcxx_check_subscript(__n);
#endif
return _M_instance[__n];
}
const_reference
operator[](size_type __n) const
{
#ifdef _GLIBCXX_DEBUG
__glibcxx_check_subscript(__n);
#endif
return _M_instance[__n];
}
这意味着您可以像对 vector 和其他 STL 调试一样启用数组边界检查 - 通过将 -D_GLIBCXX_DEBUG
添加到编译行。例如:
g++ someAwesomeProgram.cpp -D_GLIBCXX_DEBUG
我刚刚查看了 gcc 主干,显然还没有对数组的 _GLIBCXX_DEBUG 的引用:(。http://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/include/std/array
希望它不会太远。我想我们很快就会在 Debug模式下拥有安全的迭代器和所有用于数组的迭代器。与此同时,这可能是我们的小 secret :-)。
关于c++ - "Debug"版 GCC 中 std::array 的绑定(bind)检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8181887/