[TEST] Throws "Escaping" both BOOST_CHECK_THROW and try{}
I'm running Windows 10, 64-bit; MinGW 64-bit; GCC 5.3 64-bit; and BOOST 1_60_1 Here is the relevant test code: [319] BOOST_CHECK_THROW(throw std::out_of_range("BOOST_CK_THROW test"), std::out_of_range); [320] try { [321] std::cerr << "arcsSize()" << std::endl; [322] empty1.arcsSize(Operand::DEFAULT_ARC_SET+1); [323] std::cerr << "arcsSize() did not throw" << std::endl; [324] }//try [325] catch (const std::out_of_range& ex) [326] { std::cerr << "out_of_range caught=|" << ex.what() << "|" << std::endl; } [327] catch (...) { std::cerr << "something else caught" << std::endl; } [328] [329] BOOST_CHECK_THROW(empty1.arcsSize(Operand::DEFAULT_ARC_SET+1), std::out_of_range); The original code was just the last line, line [329]. [319]-[327] was added in an attempt to characterize the problem. The error [329] got by itself was: terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1) This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. SIGABRT intercepted; converted to exit(EXIT_FAILURE). arcSize() is implemented with std::vector::at() and the index is out-of-range, so it's supposed to throw std::out_of_range. That's what was detected, so why did it terminate the program? (The last line comes from my SIGABRT handler. Without it, the test executable ends up locked and can't be deleted.) Adding in all of the test lines shown above gives; [319] Operand_Test.cpp(319): info: check 'exception "std::out_of_range" raised as expected' has passed [321] arcsSize() terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1) This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. SIGABRT intercepted; converted to exit(EXIT_FAILURE). Notice the explicit throw in line [319] is detected and handled properly. However, the arcSize() call from inside the try block throws, but is not caught by even catch(...) {}. Can anyone help me see what's going on here? Merrill Cornish
On 9/02/2016 13:53, Merrill Cornish wrote:
I'm running Windows 10, 64-bit; MinGW 64-bit; GCC 5.3 64-bit; and BOOST 1_60_1 [...] terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. SIGABRT intercepted; converted to exit(EXIT_FAILURE). [...] arcSize() is implemented with std::vector::at() and the index is out-of-range, so it's supposed to throw std::out_of_range. That's what was detected, so why did it terminate the program? (The last line comes from my SIGABRT handler. Without it, the test executable ends up locked and can't be deleted.)
Do you have a throw-specification or noexcept on the arcSize() method? Throwing any exception type not listed in the specification will result in this sort of behaviour.
On 2/9/2016 12:58 AM, Gavin Lambert wrote:
Do you have a throw-specification or noexcept on the arcSize() method?
Gavin, Thanks for your reply. I didn't have my own out-of-range check in the case of arcSize() since I deliberately used vector::at() which does its own check and raises std::out-of-range rather than use vector::operator[] which does not check. The original error message that started me looking into this was "terminate called after throwing an instance of 'std::out_of_range'", so the at() raised the exception I told the BOOST_CHECK_THROW to look for. Merrill
On 10/02/2016 05:09, Merrill Cornish wrote:
On 2/9/2016 12:58 AM, Gavin Lambert wrote:
Do you have a throw-specification or noexcept on the arcSize() method?
I didn't have my own out-of-range check in the case of arcSize() since I deliberately used vector::at() which does its own check and raises std::out-of-range rather than use vector::operator[] which does not check. The original error message that started me looking into this was "terminate called after throwing an instance of 'std::out_of_range'", so the at() raised the exception I told the BOOST_CHECK_THROW to look for.
That's not what a throw-specification means. This is a clause on the method itself that looks like "throw()" or "throw(some-exception-type)" or "noexcept" etc. If you have one of those on *any* method in the call chain between at() and the test, then when at() throws an exception and this exception is not caught by a method that has the throw-spec, then terminate() or unexpected() (which in turn calls terminate() by default) will be called. The message suggests that this is what is happening, which is why I asked. If you're still confused by this, then post the complete declaration and definition (header and source) of the arcsSize method, and any other methods between that and the std::vector::at() call.
I understand about throw() and noexcept. In this particular case, arcSize() is basically a one line wrapper around at(), so there's no "chain" between the at() and the BOOST_CHECK_THROW. DiGSE::size_T Operand::arcsSize(DiGSE::size_T arcSetIndex) const noexcept { return d_ptr->mArcSets.at(arcSetIndex).first.size(); }//arcsSize() using arcContainer_T = std::vector< arc_T >; using namedSet_T = std::pair< arcContainer_T, std::string >; using arcSetContainer_T = std::vector< namedSet_T >; arcSetContainer_T mArcSets;
As you suggested, the problem is that I have a noexcept in a function that I am expecting to throw on occasion. I should have read the code I returned closer before hitting send. To my (slight) credit, I have been careful to remove the noexcept declarations from other functions what I expect to throw. Thanks for your time and sorry for my head wedge. Merrill Cornish
On 11/02/2016 14:37, Merrill Cornish wrote:
As you suggested, the problem is that I have a noexcept in a function that I am expecting to throw on occasion. I should have read the code I returned closer before hitting send. To my (slight) credit, I have been careful to remove the noexcept declarations from other functions what I expect to throw.
Thanks for your time and sorry for my head wedge.
Always happens sooner or later. That's why it's a good idea to get fresh eyes on the code that "can't possibly be doing that". :)
participants (2)
-
Gavin Lambert
-
Merrill Cornish