Disabling bounds checking for c++ vectors
Asked Answered
L

8

14

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.

Larceny answered 5/3, 2010 at 3:15 Comment(6)
To what end? There may be a better way.Ridge
You should be able to use a regular expression to replace at() with [], and set a breakpoint to help verify that all instances were replaced. Not that one slipping through would be a disaster, the concern is just performance, right?Neomineomycin
Why would you want to do this? If your answer is performance, then please tell me you've profiled and found that this is your bottleneck. If that's the case, then yes, rewrite your at()s as []. Otherwise, let it be.Apeak
@Adam: And not all the ats either, just the hotspots. :-PAndvari
@Adam: I have profiled it with oprofile, and the program uses a lot of time in libstdc++, so I want to check whether this is due to bounds checking. I want to keep bounds checking during development, but possibly disable it when I run it for real.Larceny
You should pinpoint the exact location of bottleneck. Maybe your code spends 80% of time in malloc() having nothing to do with bounds checking :)Oday
G
27

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.

Gyneco answered 5/3, 2010 at 7:37 Comment(1)
+1 Late to the party, but bearing excellent advice. This is definitely the quick-and-dirty way to profile something.Nicosia
A
15

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.

Andvari answered 5/3, 2010 at 3:18 Comment(0)
P
6

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

Pase answered 5/3, 2010 at 3:35 Comment(0)
M
5

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) = ...;
Montreal answered 5/3, 2010 at 8:12 Comment(1)
This should be the accepted answer since it works well and doesn't break unrelated code like Andrew Stein's solution with the #define.Internationalism
D
4

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:

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

Deuteron answered 26/12, 2015 at 2:21 Comment(0)
S
3

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.

Salivate answered 5/3, 2010 at 3:18 Comment(0)
A
2

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.

Alanealanine answered 5/3, 2010 at 8:17 Comment(1)
-1: never inherit from STL types, they lack virtual destructors.Emancipator
B
0

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

Buoyage answered 5/3, 2010 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.