问题
// The following code works fine, throwing a std::out_of_range exception:
std::vector<double> vd{ 1.5 };
try {
int i{ -1 };
double d = vd.at(i); // exception is thrown
}
catch (std::out_of_range& re) {
std::cout << "Exception is " << re.what() << std::endl; // invalid vector subscript
}
If I access vector elements in a for loop with an invalid index, no std::exception
is thrown although I use .at()
. Why is the std::out_of_range
exception not thrown?
// in a for loop, this does not throw the exception!
std::vector<double> vd{ 1.5 };
try {
for (int i = -1; i < vd.size(); ++i)
double d = vd.at(i); // exception is not thrown. Why?
}
catch (std::out_of_range& re) {
std::cout << "Exception is " << re.what() << std::endl; // exception is not thrown
}
回答1:
Because the loop does not execute. -1 < vd.size()
is false.
size()
returns an unsigned value. So before comparing the two numbers -1
is converted into an unsigned value. This conversion is done modulo the largest unsigned
value plus one, which means that -1
is converted to the largest possible unsigned
value. That is then compared with the size of your vector, and that comparison is always false.
Signed/unsigned comparsions are problematic for this reason. Although well defined, they don't work in the mathematically expected way if the signed value is negative. Your compiler should warn you about this problem.
来源:https://stackoverflow.com/questions/64884080/stdout-of-range-exception-is-not-thrown