开发者

Disabling bounds checking for c++ vectors

开发者 https://www.devze.com 2022-12-22 03:46 出处:网络
With stl::vector: vector<int> v(1); v[0]=1; // No bounds checking v.at(0)=1; // Bounds checking 开发者_C百科Is there a way to disable bounds checking without having to rewrite all at() as []?

With stl::vector:

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

开发者_C百科Is there a way to disable bounds checking without having to rewrite all at() as []? I am using the GNU Standard C++ Library.

Edit: I changed at() to [] in the area where I suspected a bottleneck, and it significantly reduced the computation time. However, since I iterate between developing the code and running experiments with it, I would like to enable bounds checking during development and disable it when I run the experiments for real. I guess Andrew's advice is the best solution.


If you really want to do it (at least for a quick and dirty profiling comparison), this will work if you have no other at()s

#define at(x) operator[](x)

And if you want to keep at() for development and use operator[] in production, just wrap it in an #ifdef.

And if you do have other at()s you can always edit your #included <vector> file.


No. The bounds-checking of std::vector::at is specified by the standard, and there is no standard-conforming C++ implementation that can deviate from that.


Maybe a better solution is to use [] and use checked implementation of the standard library for debug.


Based on your comment that you would like to turn on/off bounds checking, you could use a wrapper template function:

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
}

You would have to modify your code to enable this, but once you had it in place you could turn bound checking on or off as you wish.

I do admit that it looks a bit ugly to use:

deref(vec, 10) = ...;


Use at() when you always want checking. Also note that this throws an exception on error, so it is potentially recoverable. If you want the faster, unchecked, accessor, use [], but algorithms that use this should be tested thoroughly because the failure mode is more severe (undefined behavior).

A couple of approaches to development-mode bounds checking for [] when using GCC on Linux:

  • Enable GCC debug mode, see also GCC STL bound checking

    -D_GLIBCXX_DEBUG

  • Run your program under the Valgrind memory checker

    valgrind (your program and args)

Some other interesting discussion: vector::at vs. vector::operator[]


Not a standard way. You could turn off exceptions in your compiler. You can do this with gcc with -fno-exceptions.

You should be wary of doing this though; your libraries (including the standard libraries) might not play nicely with exceptions turned off. Check your documentation, and threads like this one on the gcc mailing list.


Derive your own vector class in your own namespace like "uncheckedvector", and override the at() of the base vector type to use the array index.

Then use "using uncheckedvector::vector" will let you override all your uses of vector everywhere. This won't work if you're using fully qualified types anywhere though.


If you have reasonably consistent access patterns (ie/ not random access), rather than using at() or [], one approach to avoid range checking is to use iterators, using begin(), end(), and advance() or even better, through the use of the standard algorithms.

Although this doesn't solve the underlying problem of correcting at() doing range checking some implementations of the standard library (MSVC) have checked iterators for some types of builds

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号