为了避免在编写异常处理代码时堆栈catch块,我想尝试使用c ++ 11功能编写一个catch-all异常处理程序。在这样做时,我注意到在两个系统上使用Code :: Blocks IDE在Centos 7和Windows 7和8.1上都有相同的奇怪行为(你必须检查设置 - > compiler-> c ++ 11 ISO复选框让它工作。)我有两种例外,硬件除以零(number1 / number2)和合成除以零函数商(number1,number2)在零分母时抛出声明的异常。这是代码:
#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;
}
我会注释掉硬件或合成分区代码行,然后用不同的整数和实数类型构建/运行。
对于i5和i7英特尔处理器,Centos 7和Windows系统的结果相似。
当执行在所有系统上抛出声明的异常的合成除法(商)行时,它对所有整数和实数类型的工作方式相同,正确地将异常编号和声明的异常文本打印到cerr:
Exception: 12DivideByZero
非常好,没有更多的堆叠异常并且遗漏任何可能发生的异常!
但是,当为整数和实数类型执行硬件除法线(number1 / number2)时,异常处理以不同方式完全被绕过。对于像double这样的实际类型,会捕获异常并且不会打印cerr文本,出现的是在导致异常的代码之后打印的显示行,,您不应该看到以及出现的内容是所有真实类型的无限值:
Result is: inf
对于所有整数类型,你甚至没有得到它,你没有得到显示行,在Linux上它正常结束,在Windows上它死了,并寻找解决你的坏程序。
对我来说似乎很奇怪,我确信一些maven会解释c ++ 11中异常处理缺乏一致性。
两个Windows系统上的Code :: Blocks都使用最近下载的mingw32-g ++。exe进行编译,当然,Centos 7使用的是64位g ++编译器。并不是说它有任何区别,系统表现相似。
答案 0 :(得分:0)
[expr.mul] / 4 二进制
/
运算符产生商,而二进制%
运算符从第一个表达式的除法产生余数第二。如果/
或%
的第二个操作数为零,则行为未定义...
为number2
输入零时,您的程序会显示未定义的行为。这意味着任何结果都是可能的; C ++标准对此类程序的行为没有任何要求。