I often have an index out of bounds error that could easily be caught if I used .at() instead of [] to access an element in a vector or string. However, at() slows down my program by a factor of 5 because of bounds checking.
I am trying to write a macro to replace .at(someVariable) with [someVariable] this way I can just uncomment the macro instead of replacing each .at() with a [] manually. I have read the documentation on macros on cppreference.com but can't seem to devise a way to get this functionality.
In general I'd avoid this kind of macros, as they are "invisible" (so the altered semantics is subtly hidden from anyone not in the knows) and can alter functionality of code that actually expected at to throw on out of bounds, even in release builds. If anything, I'd define something that stands out, for example an all-uppercase AT.
Fortunately, this is not actually needed, as the "big three" C++ runtimes already have builtin functionality to conditionally enable boundary checking on operator[] (which has also the advantage of being more readable than at):
-D_GLIBCXX_DEBUG you get the debug version of STL containers, which perform boundary checks on operator[], plus a lot of other debug checks on iterators;_LIBCPP_DEBUG to 1;ITERATOR_DEBUG_LEVEL set to 2 (and it's already enabled by default in debug builds).Incidentally, some of these errors (those that actually overflow the allocated size, not just the "logically valid" size of the vector) may also be spotted using the address sanitizer (-fsanitize=address on gcc and clang) or valgrind (slow!) and similar tools.
Here's one way that does not involve macros - it uses c++17's if constexpr for ease:
#include <vector>
constexpr bool safe_mode = true; // or false
template<class Container>
auto at(Container& v, std::size_t i) -> decltype(auto)
{
if constexpr (safe_mode)
return v.at(i);
else
return v[i];
}
int& test(std::vector<int>& v)
{
return at(v, 6);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With