To avoid stacking catch blocks in writing exception handling code, I thought to try to write a catch-all exception handler using the c++11 features. In doing so I noticed some odd behavior that worked the same way on both Centos 7 and Windows 7 and 8.1 using Code::Blocks IDE on both systems (you have to check the settings->compiler->c++11 ISO checkbox to get this to work.) I had two kinds of exceptions, a hardware divide by zero (number1/number2) and a synthetic divide by zero function quotient(number1, number2) that throws a declared exception when there is a zero denominator. Here's the code:
#include <iostream>
#include <exception>
#include <typeinfo>
#include <stdexcept>
using namespace std;
class DivideByZero : public runtime_error
{
public:
DivideByZero() :
runtime_error("Divide by zero exception") {}
};
template <typename T>
T quotient(T numer, T denom)
{
if (denom == 0)
{
throw DivideByZero();
}
else
{
return numer / denom;
}
}
int main()
{
double number1, number2, ratio;
cout << "Enter a numerator: ";
cin >> number1;
cout << "Enter a denominator: ";
cin >> number2;
try
{
ratio = number1/number2;
//ratio = quotient(number1, number2);
cout << "Result is: " << ratio << endl;
}
catch (...)
{
std::exception_ptr p = std::current_exception();
cerr << "Exception: "
<< (p ?
p.__cxa_exception_type()->name() :
"Anonymous")
<< endl;
}
return 0;
}
I would comment out the hardware or the synthetic division code line and then build/run with different integer and real types.
The results were similar on both Centos 7 and the Windows systems, for i5 and i7 Intel processors.
When executing the synthetic divide (quotient) line that throws a declared exception on all systems, it worked the same way for all the integer and real types, correctly printing out the exception number and the declared exception text to cerr:
Exception: 12DivideByZero
Pretty nice, no more stacking exceptions and missing any that might occur!
However, when executing the hardware divide line (number1/number2) for both integer and real types, the exception handling was bypassed completely in different ways. For real types like double, the exception is caught and the the cerr text is not printed, what comes out is the display line printed after the code causing the exception, which you should not see and what appears to be the infinite value for all the real types:
Result is: inf
For all integer types you don't even get that, you get no display line and on Linux it ends normally, on Windows it dies and goes looking for a solution to your bad program.
Seems odd to me, I'm sure some maven will explain the lack of consistency in exception handling in c++11.
Aucun commentaire:
Enregistrer un commentaire