JNI - Divide by Zero. A comparison between Java and C(1)

来源:互联网 发布:聂卫平 知乎 编辑:程序博客网 时间:2024/06/05 02:29

In Java, we can use try catch to handle DivideByZero exceptions.

public class DivideByZero{public static void main(String[] args){try {int d = 5;d = d/(d-5);}catch (Exception e){e.printStackTrace();}<pre name="code" class="cpp">

result:

wsh@wsh-VirtualBox:~/JNI/JNI_CPP/JavaOnly$ java DivideByZero java.lang.ArithmeticException: / by zeroat DivideByZero.main(DivideByZero.java:5)



But in C++, try catch cannot handle it...

#include <iostream>using namespace std;int main(){try{int d = 5;d = d/(d-5);}catch(int e){cout << "Caught divide by zero exception: "<<e<<endl;}return 0;}

result

wsh@wsh-VirtualBox:~/JNI/JNI_CPP/OnlyCpp$ ./TryCatch Floating point exception (core dumped)


In order to detect DivideByZero exception, we have to manually catch and throw. Obviously, it's useless.

#include <iostream>#include <stdio.h>using namespace std;int main(){try{int d = 5;if (d-5 == 0){throw(23333);}d = d/(d-5);}catch(int e){cout << "Caught divide by zero exception: "<<e<<endl;}return 0;}

result

wsh@wsh-VirtualBox:~/JNI/JNI_CPP/OnlyCpp$ ./TryCatch Caught divide by zero exception: 23333

The reason is that DivideByZero is not regarded as an exception in C++. Look at the following citation:

Why doesn't a divide-by-zero cause an exception in C++?

It was a specific design decision of C++ not to handle divide-by-zero; whereas Java and Ada, for example, take the opposite view. Why? The usual answers -- efficiency and an assumption that C++ will tend to be used with more of an awareness of the hardware.

Stroustrup says, in "The Design and Evolution of C++" (Addison Wesley, 1994), "low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."

So you must check your divisors yourself, or discover if your hardware maps divide-by-zero onto some other kind of exception and catch that. It's fairly easy to discover the latter. Just put a try {} catch (...) {} around a divide by zero.


http://www.battersea-locksmith.co.uk/briefings/divByZeroInCpp.html

When the system got a DivideByZero exception, it will throw a SIGFPE. We need to modify the handler to print it out.

What is SIGFPE? 
8) SIGFPE在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。

#include <iostream>#include <csignal>using namespace std;//We can do more things here.//Can we print the stack trace here?void handler(int a){cout <<"Signal  "<<a <<" here!"<<endl;//change SIGFPE to the Default Valuesignal(SIGFPE, SIG_DFL);}int main(){signal(SIGFPE,handler);int d = 5;d = d/(d-5);return 0;}



result

wsh@wsh-VirtualBox:~/JNI/JNI_CPP/OnlyCpp$ ./SystemHandler Signal  8 here!Floating point exception (core dumped)


In this article, we discussed the different exception handling mechanism in Java and C. Next we'll discuss how to make use of the two mechanisms in JNI and Android.

0 0
原创粉丝点击