C++ Exception Handling

走远了吗. 提交于 2019-12-23 10:03:21

问题


So I was writing some code and I noticed that apart from syntactical, type, and other compile-time errors, C++ does not throw any other exceptions. So I decided to test this out with a very trivial program:

#include<iostream>

int main() {
    std::count<<5/0<<std::endl;
return 1
}

When I compiled it using g++, g++ gave me a warning saying I was dividing by 0. But it still compiled the code. Then when I ran it, it printed some really large arbitrary number. When I want to know is, how does C++ deal with exceptions? Integer division by 0 should be a very trivial example of when an exception should be thrown and the program should terminate.

Do I have to essentially enclose my entire program in a huge try block and then catch certain exceptions? I know in Python when an exception is thrown, the program will immediately terminate and print out the error. What does C++ do? Are there even runtime exceptions which stop execution and kill the program?


回答1:


There are runtime exceptions, but not everything that's "wrong" results in a runtime exception being thrown. For example, acccessing an array out of bounds or dereferencing a null pointer is simply "undefined behaviour" - meaning anything at all can happen. Division by zero also falls into the "undefined" category.

The rationale for some operations resulting in "undefined behaviour" rather than an exception is efficiency. Suppose an out-of-bounds array access required an exception to be thrown. Then the compiler would have to generate code for each array access to checks whether it's out of bounds, and if so, throw an exception. That's a lot of checking, most of which is unnecessary. Instead, what compilers do is just generate the instruction for the element access assuming it is within bounds. If it happens to be out of bounds, then whatever happens (e.g. segmentation fault) happens. If you want a check to be performed, you can always code it explicitly.

This makes C++ more powerful than languages that always do checks (e.g. Java or python) because you can choose when you want a check done, and when you don't. (On the other hand, it makes C++ less safe than Java or python. It's a trade-off).


As for what happens when an exception is thrown but not caught anywhere, typically compiler implementations will print an error message containing the exception's what(). In your example that's not applicable because no runtime exception is being thrown.




回答2:


Yes, there are runtime exceptions. An example is out_of_range, which is thrown by vector::at.

However, division by zero is undefined (C++0x §5.6/4):

If the second operand of / or % is zero the behavior is undefined.

So it can fail to compile, throw a made-up exception, print "some really large arbitrary number", or segfault.




回答3:


C++ only throws standard exceptions that are well defined in the C++ standard.(Yes it includes some run-time exceptions)

An Integer divided by zero is not an standard C++ exception(Technically it is Undefined Behavior). So no implicit exception will be thrown. An particular compiler might map the run-time error to some kind of an exception(You will need to check the compiler documentation for this, some compilers map divide by zero to some exception), if so you can catch that particular exception. However, note that this is not portable behavior and will not work for all compilers.

Best you can do is to check the error condition(divisor equals zero) yourself and throw an exception explicitly in such cases.

EDIT: To answer the comment

class A
{
    public:
         void f()
         {
             int x;
             //For illustration only
             int a = 0;
             if(a == 0)
                  throw std::runtime_error( "Divide by zero Exception"); 
             x=1/a;
         }

         A()
         {
              try
              {
                   f();
              }
              catch(const std::runtime_error& e)
              {
                   cout << "Exception caught\n";
                   cout << e.what(); 
              }
         }
 };     



回答4:


Visual C++ correctly flags this as a divide by zero error. So if it doesn't compile, then there is no question of running it.



来源:https://stackoverflow.com/questions/10925675/c-exception-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!