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
Related
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.
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;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm currently using a C library under C++11, the problem that I'm facing now and I never faced before, it's to handle errors and failures in a way that will be meaningful for the end user of my program.
At the moment in my C++ code there is something as assert(foo()), where foo is a function from this C library and it returns a bool which reflects the state of the operations, true everything is ok, false otherwise.
I'm wondering if there is a better way to handle this, I would like to substitute the default message with some custom error code or a different string/message. Also note that I can't modify this library, so any possible solution needs to take this into account.
The are 2 main points that concern me:
assert is for when I compile my code in debug, I will basically never use assert in production or release mode, nor assert is intended to be used like I'm using it for the moment
a good portion of this functions is highly influenced by user input, so something that works at runtime is highly needed .
What should I do ? I basically have a C function that returns a bool, it doesn't uses any C or C++ specific error handling function or macro, I should wrap it inside a try catch ?
I'm also taking into account the fact that I would like to avoid calling std::abort and I would prefer to clean up everything in case of failure.
I would use C++ exceptions.
You can use some of the already defined standard C++ exception classes, like std::runtime_error, or you can define some custom exception class (derived from e.g. std::runtime_error).
e.g.
// FooWrapper.h -- C++ wrapper around your "foo" library
#pragma once
#include <stdexcept> // For std::runtime_error
#include "foo.h" // The C library header
...
namespace Foo { // Can wrap the raw C library nicely in a namespace
// Custom exception class for your "foo" errors.
class FooError : public std::runtime_error {
public:
explicit FooError(const std::string& errorMessage)
: std::runtime_error(errorMessage) {
// Can do additional initialization stuff, and pass
// additional information regarding the particular "Foo" error,
// e.g. as another constructor parameter.
// ...
}
};
... other stuff in the wrapping header ...
} // namespace Foo
Then, in your C++ code, you can throw the aforementioned exception when foo() function call fails:
if (! foo()) {
throw Foo::FooError("Some information", ...some other error params... );
}
And you can catch that and try to recover or print a nice error message in the GUI part of your code, e.g.:
try {
// ... do something ...
} catch( const Foo::FooError& fooError ) {
// ... try to recover, or display the error message
// returned by fooError.what()
}
Note also that, since the FooError exception class is inserted into the standard C++ exception hierarchy (since it's derived from std::runtime_error), this custom exception can also be caught by C++ code already present in your code base, that tries to catch the more generic std::runtime_error or std::exception classes.
Put all entry points to the library in your code within try/catch blocks as you suggested. Then the quickest and simplest solution is
if (!foo())
throw std::runtime_error("foo(): returned false");
as needed. You can create your own exception class (possibly but not necessarily derived from std::exception when you decide you need more structured behavior, e.g. behavior which depends on exactly which function fails. In the simple case you would just have
try
{
... //The if/throw test will typically not occur here, but deeper within the call stack.
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
//do cleanup
}
or something like that. Edit: As #TNA emphasizes, you put the try/catch block at the point in the code where you are able to handle the error. The if/throw tests can occur anywhere.
If macro and go to statement can be considered, I think this can be an alternative:
#define CHECK (fn) if (!fn) \
{ \
// Set the valid error msg somewhere that can be retrieved later on..
goto QUIT; \
} \
// Usage
AnyObject Afnc()
{
AnyObject anyObj;
CHECK(foo())
QUIT:
return anyObj;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a generally accepted idiom for indicating C++ code can throw exceptions?
How do you indicate in your code when a C++ function is possible to throw something? I don't mean through documentation, but through syntax.
For example I tried placing a throw(std::exception) at the end of the function declaration, but that gave me a warning saying that "C++ exception specification ignored except to indicate a function is not __declspec(nothrow)", which I guess means the compiler ignored the throw and proceeded as if it were not there.
I also tried adding a throw() (without anything in the parenthesis) at the end of the declaration, but — contrary to my expectations — that means the function is expected to never throw anything: "function assumed not to throw an exception but does".
Atm I'm using throw(...) to syntactically indicate the function may throw as this doesn't give me any errors or warnings. Do you have any other suggestions as to how I might indicate this through syntax?
You don't. Exception specifiers do not mean "Here's what I can throw", they mean "if anything other than this gets thrown, go to std::terminate". This behavior is counterintuitive to the point that MSVC++ does not and will not support them.
The semantics of C++ is that you must assume a function can always throw.
Most of the compilers are non conforming to the standard when it comes to Exception specifications. Exceptions specifications are considered as an experiment that failed.
For example:
If you have a blank exception specification then what gets called? the unexpected() method or a bad_exception will be thrown and if both in what order?
#include "stdafx.h"
#include <stdio.h>
#include <exception>
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
void myunexpected ()
{
cerr << "unexpected called\n";
}
void doSomething(void) throw();
void doSomething(void) throw()
{
A obj;
obj.i= 100;
throw obj;
}
int _tmain(int argc, _TCHAR* argv[])
{
set_unexpected (myunexpected);
try
{
doSomething();
}
catch (bad_exception be)
{
puts("Caught something");
}
catch (A &obj)
{
puts("Caught Integer");
}
return 0;
}
If you run this code on Visual studio, you will see that the exception just gets caught by the appropriate handler.
So to conclude, Exception specifications is a failed experiment and it's best to avoid them.
Basically, throw specifiers are worthless, as was discovered after their introduction, unfortunately, and current compilers ignore them. They're deprecated, and quality libraries don't include them. Just don't bother with them. C++0x officially deprecates them, and only has a noexcept keyword.
I have a C++ class and I am trying to run it in Ubuntu:
#ifndef WRONGPARAMETEREXCEPTION_H_
#define WRONGPARAMETEREXCEPTION_H_
#include <iostream>
#include <exception>
#include <string>
using namespace std;
#pragma once
class WrongParameterException: public exception
{
public:
WrongParameterException(char* message): exception(message) {};
virtual ~WrongParameterException() throw() {};
};
#endif
when I try to compile it, the compiler gives me this error:
WrongParameterException.h: In constructor ‘WrongParameterException::WrongParameterException(char*)’:
WrongParameterException.h:14: error: no matching function for call to ‘std::exception::exception(char*&)’
/usr/include/c++/4.3/exception:59: note: candidates are: std::exception::exception()
/usr/include/c++/4.3/exception:57: note: std::exception::exception(const std::exception&)
Can anyone tell me what am I doing wrong? I tried changing the message variable to string or const string or const string& but it didn't help.
Here is how I use the new exception that I created from main:
try
{
if ((strToInt1 == -1) || (parameters[1] == NULL) || (strToInt3 == -1) || (parameters[3] != NULL))
{
throw WrongParameterException("Error in the config or commands file");
}
}
catch(WrongParameterException e)
{
log.addMsg(e.what());
}
First, #pragma once is the wrong way to go about it, learn about header include guards. Related question on SO explains why using #pragma once is the wrong way to go about it. Wikipedia explains how to use include guards which serve the same purpose without any of the downsides.
Second, you are calling the constructor of std::exception with a parameter it does not know, in this case a pointer to a character array.
#include <stdexcept>
#include <string>
class WrongParameterException : public std::runtime_error {
public:
WrongParameterException(const std::string& message)
: std::runtime_error(message) { };
};
Would probably be what you want. For more information on exceptions, check out C++ FAQ Lite article on Exceptions and the exceptions article at cplusplus.com.
Good luck!
std::exception does not have a constructor that takes any kind of string, only a virtual what() method that returns the exception description.
You will have to store the string yourself and return it from there.
My advice would be:
Inherit from std::runtime_error. As advised by X-Istence above. It is conceptually a runtime error, and also the std::runtime_error constructor accepts a std::string as argument describing what happened.
About your catching the exception. I'd use catch(WrongParameterException const& e)
(note the const reference) instead of catch(WrongParameterException e), because first, the exception is normally constant in your case, and, also, using the reference, you catch any subclass of WrongParameterException in case your code evolves with some more refined exception handling.
std::exception's constructor doesn't take a string argument. You're trying to give it one, which is what causes the compile error.
You need to store your string, which would be better to handle as a std::string rather than a raw pointer, and return it from the what() method.
Looking at the declaration of the exception class in MS VS2K5, the constructor you want is:
exception (const char *const&);
so try changing your constructor to:
WrongParameterException (const char *const message)
and see if that helps. Otherwise, store the pointer in your own class and implement all the relevant methods.
A simple solution is to design your exception diferently. Here is a simple example:
class MyException : public Exception
{
public:
MyException(CString strError) { m_strError = strError; }
CString m_strError;
};
Then you can simply use your exception message as you please. This is because Exception does not have a contructor that excepts a String, so you have to stlre it on your own.