ByronB
ByronB

Reputation: 100

std::out_of_range exception is not thrown

   // 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
    }

Upvotes: 3

Views: 339

Answers (1)

john
john

Reputation: 87959

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.

Upvotes: 15

Related Questions