std::vector range check

M

mk

I will have 2 build types of my program: debug and release. In debug
build I want std::vector indexing operation (operator[] or at()) to do
a range-check. In release build I don't want it.

What is the easiest way to achieve that?

I currently have couple solutions, each one with drawbacks:

1. each time I change a build, search-and-replace in whole code
vector::eek:perator[] with at() or vice-versa (this is not really a
solution of course)

2. derive a class from std::vector and override operator[] to do what
I need based on DEBUG macro.

This has a drawback of using non-standard class name (e.g. Vector)
that can potentially confuse future maintainers of the program.
Additionally, operator[] is not virtual, so overriding it is not
entirely safe, as the old one can be invoked accidentally under some
circumstances.

cheers,
Marcin Kalicinski
 
J

John Carson

mk said:
I will have 2 build types of my program: debug and release. In debug
build I want std::vector indexing operation (operator[] or at()) to do
a range-check. In release build I don't want it.

What is the easiest way to achieve that?

I currently have couple solutions, each one with drawbacks:

1. each time I change a build, search-and-replace in whole code
vector::eek:perator[] with at() or vice-versa (this is not really a
solution of course)

2. derive a class from std::vector and override operator[] to do what
I need based on DEBUG macro.

This has a drawback of using non-standard class name (e.g. Vector)
that can potentially confuse future maintainers of the program.
Additionally, operator[] is not virtual, so overriding it is not
entirely safe, as the old one can be invoked accidentally under some
circumstances.

cheers,
Marcin Kalicinski


How about:

#ifdef _DEBUG
#define at(x) at(x)
#else
#define at(x) operator[](x)
#endif
 
I

Ivan Vecerina

:I will have 2 build types of my program: debug and release. In debug
: build I want std::vector indexing operation (operator[] or at()) to do
: a range-check. In release build I don't want it.
:
: What is the easiest way to achieve that?
Use a non-member function that does what you want.
Something like [just typing on-the-fly]:
template<class C>
C::reference at(C& container, C::size_type index)
{
#ifdef NDEBUG
return container[index];
#else
return container.at(index);
#endif
}
// and a const version as well...

: I currently have couple solutions, each one with drawbacks:
:
: 1. each time I change a build, search-and-replace in whole code
: vector::eek:perator[] with at() or vice-versa (this is not really a
: solution of course)
Not a reasonable option.

: 2. derive a class from std::vector and override operator[] to do what
: I need based on DEBUG macro.
Not a good idea either. Only create a new class when you have
new data members or new invariants to enforce.



Regards,
Ivan
 
S

Stephen Howe

I will have 2 build types of my program: debug and release. In debug
build I want std::vector indexing operation (operator[] or at()) to do
a range-check. In release build I don't want it.

What is the easiest way to achieve that?

Preprocessor Macros are frowned on as a whole but I use the following for
vector and deque:

#if defined(_DEBUG)
#define AT(x) at(x)
#else
#define AT(x) operator[](x)
#endif

and then have something like

std::vector<int> v;
// later
int i = v.AT(0);

You can still use [] if you know you have checked the size() (or .at() if
not)

Stephen Howe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top