make_shared in a try catch - scoping issue - c++

I need to allocate memory, but I would like to do this in a try/catch, but that introduces a new scope, in which the variable is then not available once I'm out of the try-scope. What's the best way to solve this?
try {
auto something = std::make_unique<SomeClass>;
}
catch (std::bad_alloc) {
...
}
// ... lots of code I don't want to include in the try/catch-scope.
something.callSomeMethod();
How to I go about solving this?

There is a specific reason why what you are doing shouldn't work. If the code you wrote worked the way you wrote it, then you would be calling callSomeMethod() on a null object. The right way to do it as Benjamin Lindley said, is to put that code in your try block. That way the variable is in-scope but the method call will only happen if there was not a bad alloc that threw an exception.

For posterity, and in case you needed to do something else in your try block that would not result in an invalid pointer (because, as has been mentioned there is a reason what you're trying to do doesn't work). If you're trying to do something else and still want to execute your operations on something afterward, the following code will do what you want:
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
int main()
{
class SomeClass { public: int a; void callSomeMethod() const {} };
std::unique_ptr<SomeClass> something{};
try {
something = std::move(std::make_unique<SomeClass>());
// operation that might throw other_exception
}
catch (const other_exception& e) {
std::cout << "bad" << std::endl;
}
// ... lots of code I don't want to include in the try/catch-scope.
something->callSomeMethod();
return 0;
}

As other answers have mentioned, your code should generally be within the try/catch block, since it doesn't have any meaning if the exception is caught. I'm not sure what your reason is for not wanting to include the code in the try/catch, since you're implying something.callSomeMethod() depends on lots of code, and lots of code depends on std::make_unique. If lots of code isn't dependent, you can delay std::make_unique until after lots of code.
I think it might be worth clarifying, the purpose of exceptions is to abort and handle an exceptional situation. The exceptional situation is that execution of following code can be impacted. So, any code that would be impacted, or transitively code that depends on it, should be included in the try/catch block. This is the minimal scope, by definition, and it's the scope you should use. Nothing more, nothing less.
Sometimes the code to handle an exception can be shared across functions that throw exceptions, but it's still generally best to narrow the scope and write the necessary specific handling code for each one.
It might be worth noting that almost nothing can be done for std::bad_alloc, so it's generally not an exception worth catching. Also, you should generally catch exceptions by reference unless you have a reason to do otherwise. So, your code should look something like this...
try {
auto something = std::make_unique<SomeClass>;
// ... lots of code I don't want to include in the try/catch-scope.
something.callSomeMethod();
}
catch (std::exception& e) {
// you dun goofed...
}

If you really must use something outside the try/catch block (and no, you really mustn't, but if you insist...) then it's a good idea to make it impossible to give yourself a segfault.
calling a method on a null unique_ptr is a sure way to disaster, plus the initialisation of the unique_ptr requires an un-necessary memory allocation.
Another way is to use boost::optional :
#include <iostream>
#include <boost/optional.hpp>
using namespace std;
int main()
{
class SomeClass { public: int a; void callSomeMethod() const {} };
boost::optional<SomeClass> something{};
try {
something = SomeClass();
// operation that might throw other_exception
}
catch (const std::exception& e) {
std::cout << "bad" << std::endl;
}
// ... lots of code I don't want to include in the try/catch-scope.
if (something) {
something.get().callSomeMethod();
}
return 0;
}

Related

c++, dealing with exceptions from constructors

I have a class which is loaded from an external file, so ideally I would want its constructor to load from a given path if the load fails, I will want to throw an error if the file is not found/not readable (Throwing errors from constructors is not a horrible idea, see ISO's FAQ).
There is a problem with this though, I want to handle errors myself in some controlled manner, and I want to do that immediately, so I need to put a try-catch statement around the constructor for this object ... and if I do that, the object is not declared outside the try statement, i.e.:
//in my_class.hpp
class my_class
{
...
public:
my_class(string path);//Throws file not found, or other error error
...
};
//anywhere my_class is needed
try
{
my_class my_object(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
//Problem... now my_object doesn't exist anymore
I have tried a number of ways of getting around it, but I don't really like any of them:
Firstly, I could use a pointer to my_class instead of the class itself:
my_class* my_pointer;
try
{
my_class my_pointer = new my_class(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong, and besides, I personally think it is ugly to have some objects be pointers to objects, and have most others be "regular objects".
Secondly, I could use a vector with only one element in much the same way:
std::vector<my_class> single_vector;
try
{
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
I don't like the idea of having a lot of single-element vectors though.
Thirdly, I can create an empty faux constructor and use another loading function, i.e.
//in my_class.hpp
class my_class
{
...
public:
my_class() {}// Faux constructor which does nothing
void load(string path);//All the code in the constructor has been moved here
...
};
//anywhere my_class is needed
my_class my_object
try
{
my_object.load(path);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
This works, but largely defeats the purpose of having a constructor, so I don't really like this either.
So my question is, which of these methods for constructing an object, which may throw errors in the constructor, is the best (or least bad)? and are there better ways of doing this?
Edit: Why don't you just use the object within the try-statement
Because the object may need to be created as the program is first started, and stopped much later. In the most extreme case (which I do actually need in this case also) that would essentially be:
int main()
{
try
{
//... things which might fail
//A few hundred lines of code
}
catch(/*whaveter*/)
{
}
}
I think this makes my code hard to read since the catch statement will be very far from where things actually went wrong.
One possibility is to wrap the construction and error handling in a function, returning the constructed object. Example :
#include <string>
class my_class {
public:
my_class(std::string path);
};
my_class make_my_object(std::string path)
{
try {
return {std::move(path)};
}
catch(...) {
// Handle however you want
}
}
int main()
{
auto my_object = make_my_object("this path doesn't exist");
}
But beware that the example is incomplete because it isn't clear what you intend to do when construction fails. The catch block has to either return something, throw or terminate.
If you could return a different instance, one with a "bad" or "default" state, you could have just initialized your instance to that state in my_class(std::string path) when it was determined the path is invalid. So in that case, the try/catch block is not needed.
If you rethrow the exception, then there is no point in catching it in the first place. In that case, the try/catch block is also not needed, unless you want to do a bit of extra work, like logging.
If you want to terminate, you can just let the exception go uncaught. Again, in that case, the try/catch block is not needed.
The real solution here is probably to not use a try/catch block at all, unless there is actually error handling you can do that shouldn't be implemented as part of my_class which isn't made apparent in the question (maybe a fallback path?).
and if I do that, the object is not declared outside the try statement
I have tried a number of ways of getting around it
That doesn't need to be a problem. There's not necessarily need to get around it. Simply use the object within the try statement.
If you really cannot have the try block around the entire lifetime, then this is a use case for std::optional:
std::optional<my_class> maybe_my_object;
try {
maybe_my_object.emplace(string);
} catch(...) {}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong,
A pointer returned by new is correct to delete. In the error case, simply set the pointer to null and there would be no problem. That said, use a smart pointer instead for dynamic allocation, if you were to use this approach.
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
Don't push and shrink when you know the number of objects that are going to be in the vector. Use reserve instead if you were to use this approach.
The object creation can fail because a resource is unavailable. It's not the creation which fails; it is a prerequisite which is not fulfilled.
Consequently, separate these two concerns: First obtain all resources and then, if that succeeded, create the object with these resources and use it. The object creation as such in this design cannot fail, the constructor is nothrow; it is trivial boilerplate code (copy data etc.). If, on the other hand, resource acquisition failed, object creation and object use are both skipped: Your problem with existing but unusable objects is gone.
Responding to your edit about try/catch comprising the entire program: Exceptions as error indicators are better suited for things which are done in many places at various times in a program because they guarantee error handling (by default through an abort) while separating it from the normal control flow. This is impossible to do with classic return value examination, which leaves us with a choice between unreadable or unreliable programs.
But if you have long-lived objects which are created only rarely (in your example: only at startup) you don't need exceptions. As you said, constructor exceptions guarantee that only properly initialized objects can be used. But if such an object is only created at startup this danger is low. You check for success one way or another and exit the program which cannot perform its purpose if the initial resource acquisition failed. This way the error is handled where it occurred. Even in less extreme cases (e.g. when an object is created at the beginning of a large function other than main) this may be the simpler solution.
In code, my suggestion looks like this:
struct T2;
struct myEx { myEx(const char *); };
void exit(int);
T1 *acquireResource1(); // e.g. read file
T2 *acquireResource2(); // e.g. connect to db
void log(const char *what);
class ObjT
{
public:
struct RsrcT
{
T1 *mT1;
T2 *mT2;
operator bool() { return mT1 && mT2; }
};
ObjT(const RsrcT& res) noexcept
{
// initialize from file data etc.
}
// more member functions using data from file and db
};
int main()
{
ObjT::RsrcT rsrc = { acquireResource1(), acquireResource2() };
if(!rsrc)
{
log("bummer");
exit(1);
}
///////////////////////////////////////////////////
// all resources are available. "Real" code starts here.
///////////////////////////////////////////////////
ObjT obj(rsrc);
// 1000 lines of code using obj
}

golang-style "defer" in C++ [duplicate]

This question already has answers here:
What is standard defer/finalizer implementation in C++?
(9 answers)
Closed 7 years ago.
I was reading about the go language's defer statement. It allows you to specify an action to take when a function has ended. For example, if you have a file pointer or resource, instead of writing free/delete with every possible return path, you just need to specify the defer function once.
It looks like an analogue might be coming to C++ eventually (What is standard defer/finalizer implementation in C++?, Will there be standardization of scope guard/scope exit idioms?) Until then, is there anything unforeseen about doing it with an object whose destructor makes a callback? It looks like the destructor order for local variables is sane and that it also handles exceptions well, though maybe not exiting on signals.
Here is a sample implementation... is there anything troubling about it?
#include <iostream>
#include <functional>
using namespace std;
class FrameExitTask {
std::function<void()> func_;
public:
FrameExitTask(std::function<void()> func) :
func_(func) {
}
~FrameExitTask() {
func_();
}
FrameExitTask& operator=(const FrameExitTask&) = delete;
FrameExitTask(const FrameExitTask&) = delete;
};
int main() {
FrameExitTask outer_task([](){cout << "world!";});
FrameExitTask inner_task([](){cout << "Hello, ";});
if (1+1 == 2)
return -1;
FrameExitTask skipped_task([](){cout << "Blam";});
}
Output: Hello, world!
Boost discuss this in Smart Pointer Programming Techniques:
http://www.boost.org/doc/libs/1_59_0/libs/smart_ptr/sp_techniques.html#handle
You can do, for example:
#include <memory>
#include <iostream>
#include <functional>
using namespace std;
using defer = shared_ptr<void>;
int main() {
defer _(nullptr, bind([]{ cout << ", World!"; }));
cout << "Hello";
}
Or, without bind:
#include <memory>
#include <iostream>
using namespace std;
using defer = shared_ptr<void>;
int main() {
defer _(nullptr, [](...){ cout << ", World!"; });
cout << "Hello";
}
You may also as well rollout your own small class for such, or make use of the reference implementation for N3830/P0052:
N3830: https://github.com/alsliahona/N3830
P0052: https://github.com/PeterSommerlad/scope17
The C++ Core Guidelines also have a guideline which employs the gsl::finally function, for which there's an implementation here.
There are many codebases that employ similar solutions for this, hence,
there's a demand for this tool.
Related SO discussion:
Is there a proper 'ownership-in-a-package' for 'handles' available?
Where's the proper (resource handling) Rule of Zero?
This already exists, and it's called scope guard. See this fantastic talk: https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C. This lets you easily create an arbitrary callable to be called at exit. This is the newer version; it was developed originally long before go existed.
It works perfectly in general, but I'm not sure what you mean by it handling exceptions. Throwing exceptions from a function that has to be called at scope exit is a mess. The reason: when an exception is thrown (and not immediately caught), current scope exits. All destructors get run, and the exception will continue propagating. If one of the destructors throws, what do you do? You now have two live exceptions.
I suppose there are ways a language could try to deal with this, but it's very complex. In C++, it's very rare that a throwing destructor would be considered a good idea.
This already exists in C++, and it's a tremendously bad idea and the example you gave exemplifies why it's a pointless thing to do and I hope that the Committee never introduces it.
For example, if you have a file handle, then write a class to do it for you and then you won't have to write a defer statement for every single use case, which you could easily forget to do. Or just plain get it wrong. You write one destructor, once. That's it. Then you're guaranteed for all uses of the class that it's safe. It's much safer and much easier.

Strange format for throwing exception from a constructor

Our professor gave us a shell to make a program in. In it he gave us a class called "Maker", and it is capable of throwing exceptions. I'm confused about how to throw and catch the error, given the format of the constructor that he has provided.
He gave us his own special exception header file called CycleFoundException.h, which looks like this:
#include <iostream>
#include <exception>
using namespace std;
class CycleFoundException: public exception {
// Don't add code
};
Here is the Maker.h header file:
#include "CycleFoundException.h"
class Maker
{
private:
// insert instance variables
public:
Maker(int x) throw (CycleFoundException);
};
And finally the cpp shell, Maker.cpp:
#include Maker.h
Maker::Maker(int x) throw (CycleFoundException){
//add code here
}
int main()
{
return 0;
}
I've never seen a constructor declaration like this. Why is the "throw (CycleFoundException)" be tagged onto the declaration of the constructor? Is that necessary?
And how would I throw an exception given this format? Would I still do it the same way I would otherwise, aka if a certain condition is not met then throw the exception (from within the body of the constructor)? Thanks.
This is simply a way to say what kinds of exceptions a function is allowed to throw:
Maker::Maker(int x) throw (CycleFoundException)
means that Maker::Maker(int) is only allowed to throw CycleFoundException exceptions, nothing else. This is called an "exception specification."
Note that the C++ standard has deprecated this mechanism. It should not be used anymore. You should probably inform your professor about it ;-) They were always problematic: http://mu2e.fnal.gov/public/hep/computing/standards/C++FAQ.shtml#exceptionspec

C++ - Where to throw exception?

I have some kind of an ideological question, so:
Suppose I have some templated function
template <typename Stream>
void Foo(Stream& stream, Object& object) { ... }
which does something with this object and the stream (for example, serializes that object to the stream or something like that).
Let's say I also add some plain wrappers like (and let's say the number of these wrappers equals 2 or 3):
void FooToFile(const std::string& filename, Object& object)
{
std::ifstream stream(filename.c_str());
Foo(stream, object);
}
So, my question is:
Where in this case (ideologically) should I throw the exception if my stream is bad? Should I do this in each wrapper or just move that check to my Foo, so that it's body would look like
if (!foo.good()) throw (something);
// Perform ordinary actions
I understand that this may be not the most important part of coding and these solutions are actually equal, but I just wan't to know "the proper" way to implement this.
Thank you.
In this case it's better to throw it in the lower-level Foo function so that you don't have to copy the validation and exception throwing code in all of your wrappers. In general using exceptions correctly can make your code a lot cleaner by removing a lot of data validation checking that you might otherwise do redundantly at multiple levels in the call stack.
I would prefer not to delay notifying an error. If you know after you have created the stream, that it is no good, why call a method that works on it? I know that to reduce code-redundancy you plan to move it further down. But the downside of that approach is a less-specific error message. So this depends to some extent on the source-code context. If you could get away with a generic error message at the lower-function level you can add the code there, this will surely ease maintanence of the code especially when there are new developers on the team. If you need a specific error message better handle it at the point of failure itself.
To avoid code redundancy call a common function that makes this exception/error for you. Do not copy/paste the code in every wrapper.
The sooner you catch the exceptiont the better. The more specific the exception is - the better. Don't be scared of including most of your code into a try catch blocks, apart fromt he declaration.
For example:
int count = 0;
bool isTrue = false;
MyCustomerObject someObject = null;
try
{
// Initialise count, isTrue, someObject. Process.
}
catch(SpecificException e)
{
// Handle and throw up the stack. You don't want to lose the exception.
}
I like to use helper functions for this:
struct StreamException : std::runtime_error
{
StreamException(const std::string& s) : std::runtime_error(s) { }
virtual ~StreamException() throw() { }
};
void EnsureStreamIsGood(const std::ios& s)
{
if (!s.good()) { throw StreamException(); }
}
void EnsureStreamNotFail(const std::ios& s)
{
if (s.fail()) { throw StreamException(); }
}
I test them immediately before and after performing stream operations if I don't expect a failure.
Traditionally in C++, stream operations don't throw exceptions. This is partly for historic reasons, and partly because streaming failures are expected errors. The way C++ standard stream classes deal with this is to set a flag on a stream to indicate an error has occurred, which user code can check. Not using exceptions makes resumption (which is often required for streaming ops) easier than if exceptions were thrown.

Code reuse in exception handling

I'm developing a C api for some functionality written in C++ and I want to make sure that no exceptions are propagated out of any of the exported C functions.
The simple way to do it is making sure each exported function is contained in a:
try {
// Do the actual code
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Let's say I know one exception that is often missed inside the C++ code is std::bad_alloc and I want to treat it specially I'd write something like this instead:
try {
// Run the actual code
} catch (std::bad_alloc& e) {
return ERROR_BAD_ALLOC;
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Is it possible to decompose this in some clever way so that I can globally treat some errors differently without adding a new catch statement for the exception handler around every exported function?
I'm aware of that this is possible to solve using the preprocessor, but before going down that road, I'd make sure there is no other way to do it.
You can use only one handler function for all possible exceptions, and call it from each or your API implementation functions, as below:
int HandleException()
{
try
{
throw;
}
// TODO: add more types of exceptions
catch( std::bad_alloc & )
{
return ERROR_BAD_ALLOC;
}
catch( ... )
{
return ERROR_UNHANDLED_EXCEPTION;
}
}
And in each exported function:
try
{
...
}
catch( ... )
{
return HandleException();
}
There already is a good answer. But just FYI, its called 'exception-dispatcher' idiom, see C++ FAQ.
What about:
try{
//Your code here
} catch(std::exception e)
{
return translateExceptionToErrorCode(e);
} catch(...)
{
return UNKNOWN_EXCEPTION_THROWN;
}
Jem answer is a little more simpler than this solution. But it is possible to substitute the use of a preprocessor macro with the use of templates. Something like this (more refinements you could made):
template <class T, void (T::*FUNC)()>
class CatchWrapper
{
public:
static void WrapCall(T* instance)
{
try
{
(instance->*FUNC)();
}
catch (std::bad_alloc&)
{
// Do Something 1
}
catch (std::exception& e)
{
// Do Something 2
}
catch (...)
{
// Do Something 3
}
}
};
class Foo
{
public:
void SomeCall()
{
std::cout << "Do Something" << std::endl;
}
};
int main(int argc, char* argv[])
{
Foo i;
CatchWrapper<Foo, &Foo::SomeCall>::WrapCall(&i);
return 0;
}
Do not ever use catch(...), unless you plan on more or less immediately re-throwing. You will certainly lost any error information you might have had to help you figure out the cause of the error.
I like your second scheme a little better - catch a known set of exceptions, ideally because they are the only ones your code will throw, and let the rest through - allowing the app to crash is possibly the best thing to do since you have invoked unknown behaviour it is best to "crash responsibly".
It would be a shame to loose error information at the language boundary. You really should try to translate all exceptions into an error code usable from C.
How you do it really depends on what your exception classes look like. If you control your exception class hierarchy, you can ensure that each class provides a translation using a virtual method. If not, you may still find it practical to use a translator function and test the types of the 'std::exception'-derived exception it receives to translate it into an error code, much like Jem suggested (remember: thrown exceptions will hurt performance anyway, so don't worry about the translation being slow).