Throw objects without exception

C++ allows throw to enter any objects. From exception to string and even int . But I have never seen a real world application throw anything but exception s.

My question is: which application for throw objects is no exception ?

+7
c ++ exception
source share
6 answers

From a practical point of view, there is almost 1 application for metalizing string s, int s, or anything else that is not derived from std::exception .

This is not because there is no indication for this, but because there are contraindications that suggest why you should not.

There are two main reasons why you would not want to throw anything not obtained from std::exception :

  • Exception Security. If you select, for example, std::string , and building or a copy of this string raises another exception, terminate will be called and your process will cease to exist. You will never get a chance to catch that std::string .
  • Usability. Throwing std::exception derivatives allows catch (const std::exception&) in general. If you throw away something else, you will need to catch for this case.

A good discussion of exceptions can be found here .


1 Almost no application [...]: There are exceptions for each rule, but even with the recognition of this, I never saw a legal exception to throw a derivative of std::exception .

+9
source share

More than a language function, not a language, you can throw an object and then catch it to make the function "return" something other than the normal return type.

 int aFunc() { throw foo(); // if you catch that foo, you 've imitated returning foo return 0; // ok just an int } 

That would be a terrible design choice and a type-breach offered by C ++, but let's say you have a function heavily used in a huge code base and you want to try some changes (which include changing the return type), then there was would be a dirty way to try something before actually making the change (and grep the entire code base to make the change)

EDIT:

You must carefully read the message. I said "terrible design choices" and "type safety violation proposed by C ++" and "before the actual implementation of the change." If this is not enough, I do not think that these comments or downvotes will be.

On the other hand, try changing the return type of the function used 666 times in the code base of 6e06 lines to find out that this is not what you want, after you loaded it into your version control system, and broke the compilation of several times for developers working on platforms other than you.

If there was a shortcut, would you like to know about it? Wouldn't you use it until you made that change and sent it to your code base?

Even if the answer to these questions is “NO”, I thought this post was devoted to exploring opportunities, and just mentioning it is not “evil”. I personally heard this from Bjarne’s conversation http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote-Bjarne-Stroustrup-Cpp11-Style , who later said the same thing about not using such things.

+4
source share

You drop everything you want, it will always be an exception when you drop it. Standard libraries use classes inherited from std :: exception, and this is the design choice.

If it seems to you that for numbering it’s enough to list the numbering, as an example, why force you to drop the object ...

+1
source share

I am not sure what caused this question, since you can choose the "application" in those cases when you consider it necessary.

The purpose of object exclusion is to indicate that an exception has occurred, and, as a rule, to carry with it specific information about the exception from the thrower to the handler. If one type is sufficient for your purpose, you can use this type as an exception type. If you want, you can throw away int values, std::string values ​​and everything else. It is completely up to you.

If all you want to transfer from a thrower to a handler is an int value, then the int type will serve this purpose as an exception type. That is all that is needed.

C ++ does not impose any specific requirements on types that you can throw. For this reason, there really is no such thing as an “exception” type or a “no exception” type. What is the "type of exception" and what is not is determined by you and only you in your code. You can drop something as long as you know how to catch it and how to interpret what you caught.

The first advantage of using class types to represent exceptions is that class types are freely defined by the user, that is, you can easily define as many types of exceptions as you want. Then you can use many independent, non-interfering "thread" exceptions that throw and catch only exceptions of their respective types.

The second advantage of using class types to represent exceptions is that class types are easily extensible. That is, at any time you can add additional information about the "payload" to your type of exception, and this payload will be transferred from the place where the exception was selected until the moment it was caught and processed.

If you are not interested in any of these benefits, you can simply output and catch values ​​of type int to represent your exceptions. That will work. But I'm pretty sure that you will quickly come across the limitations of this approach in terms of service and extensibility.

+1
source share

In general, any abandoned object should flow from std::exception . However, there are exceptions. Most Obvious: I worked on projects that preferred to throw an int to call exit() . Of course, this only works if main follows the convention of catching int and returning It. (The advantage of this is that all local variables will be destructed where they will not be if you call exit() .)

And in small test programs, I will often just throw a string literal (which can be caught using char const* ), which can be immediately output. (This is not a good solution for any production code, but when you experiment to find out something, it seems acceptable.)

+1
source share

As @ galop1n replied, you can drop whatever you want. But

  • They usually throw simple data objects, not pointers, to make sure that the compiler can automatically manage the memory, so throw(type()) ---> catch(type const& e) as a result
  • Usually they throw something inherited from std :: exception to meet the expectations of those who hope to catch everything that can be registered with catch(std::exception const& e) . Although you may contradict the fact that they should not catch anything that they do not know what it is.
0
source share

All Articles