tags:

views:

320

answers:

7

With stl::vector:

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

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.

+11  A: 

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.

Chris Jester-Young
+2  A: 

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.

Matt Curtis
I don't think this is a good approach but +1 for the link.
Potatoswatter
+5  A: 

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

Fred Larson
+5  A: 

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.

Andrew Stein
+1 Late to the party, but bearing excellent advice. This is definitely the quick-and-dirty way to profile something.
Chris Lutz
A: 

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

Andrew Walker
+1  A: 

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) = ...;
R Samuel Klatchko
+2  A: 

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.

SPWorley