专家已经解释了 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()
- 我可能也需要性能我已经编写了很多带有 []
的代码,但我还不够聪明,无法替换一维数组,更不用说二维数组了。
我使用海湾合作委员会4.6
Benefits of C++11 std::array
s when programming have been explained by experts, but there is one thing I would like to get from the compiler. Ability to turn ON range check that is default when using .at()
while compiling the code that uses []
.
It could be beneficial for checking range violations especially for multidimensional arrays because in that case it is less likely that range violation will cause segfault(because you often own memory around the inner array so [5000][-123]
will still likely point to memory that you own).
So I would like to know if there is a switch that will compile into machine code that checks ranges:
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
If you ask why I don't switch to .at()
- I might need the performance, also I have a lot of code with []
already written and I'm not smart enough to smart to do replace for 1D let alone 2D arrays.
I use GCC 4.6
发布评论
评论(5)
看起来gcc 4.6自带的数组还没有调试模式。这是可以理解的,因为 C++11 支持仍处于实验阶段。
有一个标志
_GLIBCXX_DEBUG
通常用于打开调试模式。如果您查看 /usr/include/c++/4.6/debug/vector:313 您会看到operator[]
有:现在,这可能是超级邪恶的(我的意思是真的 邪恶)但看起来我们可以有条件地将其添加到数组中。将 /usr/include/c++/4.6/array 的第 148-154 行从: 更改
为:
这意味着您可以像矢量和其他 stl 调试一样启用数组的边界检查 - 通过添加
-D_GLIBCXX_DEBUG 到你的编译行。例如:
我刚刚查看了 gcc trunk,显然还没有对数组的 _GLIBCXX_DEBUG 的引用:(。 http://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/include/std/array
希望它不会太远,我想我们会有安全的迭代器。调试模式下的数组很快就完成了,这可以是我们的小秘密:-)。
It looks like the array that comes with gcc 4.6 doesn't have a debug mode yet. Understandable since C++11 support is still experimental.
There is a flag
_GLIBCXX_DEBUG
which is usually used to turn on debug mode. If you look at /usr/include/c++/4.6/debug/vector:313 you'll seeoperator[]
has:Now, this may be uber-evil (and I mean really evil) but it looks like we can conditionally add this to array. Change lines 148-154 of /usr/include/c++/4.6/array from:
to:
This means you can enable bounds checking for array the same way you do for vector and other stl debugging - by adding
-D_GLIBCXX_DEBUG
to your compile line. E.g.:I just had a look at gcc trunk and apparently there is no reference to _GLIBCXX_DEBUG for array yet :(. http://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/include/std/array
Hopefully it's not too far away. I imagine we will have safe iterators and all that for array in debug mode soon enough. In the meantime, this can be our little secret :-).
应该做这项工作。只需在整个代码库中一致使用
at(arr, pos)
即可。Should do the job. Just use
at(arr, pos)
consistently throughout the codebase.您可以模拟您想要的行为:
它与
std::array
并不完全匹配,但如果这对您很重要,则可以修复。然后将所有对std::array
的引用替换为my_array
,您将获得用于调试版本的范围检查operator[]
。(我已经使用模板别名来简化 NDEBUG 代码,但我还无法在我的编译器上实际测试它)
You can emulate the behaviour you desire:
It doesn't perfectly match
std::array
, but that could be fixed if it matters to you. Then replace all reference tostd::array
withmy_array
and you'll get range checkedoperator[]
for debug builds.(I'd have used template aliases to simplify the
NDEBUG
code, but I can't actually test that yet on my compiler)与其说它是gcc,不如说是gcc 附带的
libstdc++
标准库实现(如果您愿意,您可以自由地使用其他实现)。libstdc++
有一个可用于调试 -D_GLIBCXX_DEBUG,但是您应该注意,此调试模式会更改类型的 ABI,因此您需要与也已启用此调试模式编译的库的链接。这可能会很痛苦。libc++
是另一个实现(接近 C++11 兼容),它首先针对 Clang,但应该适用于任何兼容的编译器。它的目的是维护 ABI 兼容性,无论是否启用调试。不过,它在 OS X 之外并不完全稳定(主要是由于区域设置),因此可能无法在您的环境中使用。请注意,这两个库都是免费软件,因此如果未实施检查,您完全可以提交补丁。
It is not so much gcc as
libstdc++
the Standard Library implementation that comes with gcc (you are free to use another implementation if you wish).libstdc++
has a preprocessor flag that can be used for debugging -D_GLIBCXX_DEBUG, however you should note that this debug mode changes the ABI of the types, and thus you need to link with libraries that have also been compiled with this debug mode enabled. It can be painful.libc++
is another implementation (nigh C++11 compliant) that is first aimed at Clang but should work on any compliant compiler. It aims at maintaining ABI compatibility whether debugging is enabled or not. It's not fully stable outside of OS X though (mostly because of locale) so might not be usable in your environment.Note that both those libraries are Free Software, so if the check is not implemented, you can perfectly submit a patch.
我想要类似的东西,所以写了这个小标题工具
这允许您执行 set(arr, pos, value) 和 get(arr, pos) 以及
可以启用中止、断言或允许其继续
崩溃,没有检查。
https://github.com/goblinhack/c-plus-plus- array-bounds-checker
其要点如下(我在 github 上也有 2 维和 3 维示例)
对于调试版本:
实现的一些细节:
如果您想包含 set() 和get() 调用,启用:
在越界时打印断言(并继续):
在断言上调用 abort():
hth
I wanted something similar, so wrote this small header only tool
that allows you to do set(arr, pos, value) and get(arr, pos) and
can either enable abort, assert, or allow it to continue on and
crash, with no checking.
https://github.com/goblinhack/c-plus-plus-array-bounds-checker
The gist of it is as follows (I have 2 and 3 dimensional examples too on github)
For debug builds:
Some details of the implementation:
If you want to include a trace of set() and get() calls, enable:
To print an assertion on out of bounds (and continue):
To call abort() on assertion:
hth