Classes that don't throw but depend on the libraries that make

I have written several classes that do not throw exceptions, but use STL, and STL can throw exceptions. For example, in my class there are functions that use std :: vector, std :: list, std :: string. STL can throw when copying a string or creating a vector, right? Therefore, I cannot describe my classes as an exception for free, right?

What are you guys doing in this case? Do you combine every function in try / catch? How do you describe your class? Thanks

+6
source share
5 answers

That's right, if something you call from a specific member function (including constructors, implicit calls that the compiler provides for you, etc.) can throw an exception, then the member function can throw an exception. So this is no exception for free.

What to do about it: it really depends on what your code should do, and "what you can do if it throws an exception." You probably want to catch it SOMEWHERE, but since the scenario is most likely that you did something stupid and / or ran out of memory, you probably won’t be able to do much in this situation. (Of course, if you use, for example, std::vector::at() value out of range, then it will throw an exception - that "do something stupid" - similar to what I did a couple of times, const char* p = 0; .... std:string str(p); - this may, of course, fail, and not an exception, but my compiler seems to throw a bad_something exception from this). Any of these things, if they are not intended, are probably "the death of your code anyway." If you use std::vector::at() with a poor index, and you "intended it", then you will probably think about your design - exceptions are "expensive" compared to if (vec.size() > index) ... else ...

I'm not sure if there is a specific term for "my class does not throw exceptions, but uses a standard library that can do it."

+4
source

Fortunately, the possibility of throwing STL classes due to distribution problems is very small: it is more likely that your process will be killed by the OOM-killer than if the distribution was unsuccessful. Therefore, I prefer to ignore these exceptions and just let them crash the program. I'm pretty radical in that I don't use exceptions otherwise, so I don't have try{}catch(){} code in the code I'm writing.

When I'm not alone in the project, I also do not try to wrap any function call, I just declare my functions as throw() . This leads to the fact that any unexpected exception that comes out of any other function that I call will safely lead to the crash of the program, and not to the propagation of any other function that can catch it. Thus, I can be sure that no vital part of my code will be skipped if someone does not notice.

+1
source

Refer to GotW # 82 ( http://gotw.ca/gotw/082.htm ), always a bad ideal for adding exception specifications:

Exception specifications may lead to unexpected performance results for example, if the compiler disables nesting for functions with exception specifications. A run-time error () is not always what you want to make for those errors that exclude the specification for catching. You generally cannot write useful exception specifications for function templates anyway, because you usually cannot determine what type they can work for.

+1
source

Your design is flawed.

I have written several classes that do not throw exceptions, but use STL, and STL can throw exceptions.

You need to answer the question: what will you do if your program fails due to STL failure? Your only options are to throw an exception or return a value. (Or the application crashes in place.) One option that you have is to return a custom class that you write SuccessOrFailure . If successful, it will contain actual data about the return, and if it fails, it will contain some information describing what went wrong. In other words, you can hush up the exception that would be thrown into the return value, and make the client code check the return value for the error and do what it would do if you selected the exception, only to write a C-style return that was one from C programming bans before exceptions were invented. But if this is your design decision, this is what you need to do.

Or you can try to return some value that means "failure", for example, for an integer, return 0 or -1. This solution, of course, will work only if your actual function explicitly returns only positive numbers, and if you use a fixed number, it will not reveal any error information.

My point: you need to figure out how to handle failures, whether you throw an exception or not. "Do not use exceptions" does not answer the question, it simply ignores the work.

The only valid reasons for not using exceptions that I have seen are

  • you maintain the old return-oriented code, in which case you need to do some superficial work to turn your exceptions into different return codes.
  • you can handle all your errors (like mixing or a log library), in which case you should wrap try / catch and handle all your errors.
+1
source

In modern C ++, you can use noexcept .

 struct Foo { void bar() noexcept(true) { some_function_that_throws(); } }; void safe_function() { // safe as nothing here can ever throw Foo* foo = new(std::nothrow) Foo(); if (foo) foo->bar(); delete foo; } 

The caveat here is that the process will terminate if an exception is thrown and not caught inside the method with noexcept. Some may be considered good; this is similar to using assert. The behavior, ultimately, seems to be that you don’t have to worry about exceptions, because an uncaught exception usually terminates the process. The main difference is that the religious use of noexcept functions, when appropriate, can produce faster and more compact code (even in the so-called “redundant airlines” ABI).

In some industries, simply compiling with -fno exceptions or the equivalent is common practice. STL implementations usually support this mode. Some of them offer somewhat non-standard behavior for checking or fixing failures in cases where such checks are necessary. Keep in mind that most STL exceptions occur at some level due to lack of memory, and there is rarely a lot of recovery that you could do, even with exceptions; just a glitch is not much different from what else will happen. There are applications in which the handling of these situations is important, but the overwhelming factors are that you are not working on one of them (and if you, C ++, may not be the best choice of language).

+1
source

All Articles