class CheckPointer {
public:
CheckPointer(int * mbeg, int * mend) :
beg(mbeg), end(mend), curr(mbeg) {}
// subscript operator
int & operator[] (const size_t pos) {
if (beg + pos < beg) {
throw out_of_range("ERR: before beg!");
}
if (beg + pos >= end)
throw out_of_range("ERR: end or past end!");
return *(const_cast<int *>(beg + pos));
}
private:
const int * beg;
const int * end;
int * curr;
};
I have defined a subscript operator for the class CheckPointer. As the @param pos is of type size_t, I cannot check whether the user has passed a positive or negative value. Howerver I try to write the code to do the bound-check instead and it works :
if (beg + pos < beg) {
throw out_of_range("ERR: before beg!");
}
I don’t know why it works… Could any one help me?
Thank you for considering my question!
For more information:
Environment: eclipse CDT, Ubuntu 10.04
test-code:
int iarr[6] = {1, 2, 3, 4, 5, 6};
CheckPointer cp(iarr, iarr+6);
// subscript
cout << cp[2] << endl;
cout << cp[5] << endl;
cout << cp[-2] << endl; // error: before beg
test-code_output:
terminate called after throwing an instance of 'std::out_of_range'
what(): ERR: before beg!
3
6
This works because the negative value is cast to an unsigned value. Your machine architecture probably uses two’s-complement for negative values, so a value of -2 results in:
When you add this to
beg, it wraps around and providedbegis greater than or equal to 2, has the effect of subtracting 2 from it. Thus, despite the index being extremely large, it has essentially performed a subtraction. If the value ofbegwas1or0, the error would be “past end” instead.