C++ Exception Handling between Classes - c++

I'm working on exception handling and right now I'm stuck on a problem I'm working on out of my book. What I'm trying to do is add an try-catch block inside my main function to catch an exception that is thrown by a function that I am using. Here are snippets of where I am having trouble on.
EmptyStackPopException is an empty Exception class that I put into my stack.h file that can be seen here:
class EmptyStackPopException {
};
Here is the function that is supposed to throw this Exception.
T Stack<T>::pop( ) throw (EmptyStackPopException)
{
if (isEmpty( ))
{
throw EmptyStackPopException();
}
T result = top->getData( );
Node<T> *discard;
discard = top;
top = top->getLink( );
delete discard;
return result;
}
Here is a snippet of my main function where the exception is supposed to be caught:
try {
cout << s.pop( );
} catch (EmptyStackPopException) {
cout << "EmptyStackPopException: You didn't enter anything in." << endl;
}
Now the issue that I'm having is I cannot compile because of these following errors:
..\assignment8\main.cpp(29) : error C2061: syntax error : identifier 'EmptyStackPopException'
..\assignment8\main.cpp(29) : error C2310: catch handlers must specify one type
..\assignment8\main.cpp(32) : error C2317: 'try' block starting on line '27' has no catch handlers
I'm pretty sure that the only error I have at the moment is in the main function, EmptyStackPopException is not able to be detected in the client program which causes the last two errors.

You must specify a type with your catch statement. This should fix the three syntax errors your presented
try {
cout << s.pop( );
} catch (EmptyStackPopException& exception) {
cout << "EmptyStackPopException: You didn't enter anything in." << endl;
}
You needed to create 'exception'.
If including your EmptyStackPopException header doesn't work (based on context I'm not sure it will), the problem might be based on circular dependency, which means that two header files are including each other. I can't tell from context but this sometimes gives me the "syntax error : identifier" error.

Related

Function abi::__cxa_current_exception_type() returns non-ASCII characters

I'm running into an issue where running on a remote machine (but not locally) results in an unexpected exception of unknown type. I attempted to get more diagnostic information by wrapping things with a try {} catch {} with a range of possible exception types (including std::exception const &) but the exception still falls through to the catch(...) clause.
For lack of a better option, I attempted to get the type of the exception with (the GCC/Clang specific function) abi::__cxa_current_exception_type()->name() (within the catch(...) block), but this results in an output with non-ASCII characters. (Specifically, I'm getting 0��m- printed.) Attempting to pass it through abi::__cxa_demangle() before printing doesn't seem to help:
try {
// code which throws the exception
} catch (std::exception const & e) {
std::cout << "std::exception: " << e.what() << '\n';
} catch (...) {
int status = 0;
std::cout << "__cxa_current_exception_type() reports error type as: " << abi::__cxa_demangle( abi::__cxa_current_exception_type()->name(),0,0,&status) << '\n';
}
I'm a little surprised that the mangled name contains non-ASCII characters. (And to be explicit, we don't use non-ASCII identifiers in our code, and I'm not aware of any of our dependencies doing so.) I've also attempted to read through some name mangling resources to figure out what might be going on with the 0��m-, but I didn't find any likely reasons for the leading 0, or why there might be non-ASCII characters in the mangled name.
Do people have any ideas as to what might be going on here, and what sort of exception type is being thrown here? Or alternatively, are there approaches I may have missed to figure out the type?

Boost unit testing exception check failing strangely

I'm basically lost on this one. I've looked at Boost doc plus searching on SO, but I don't seem to find a thing. Assuming a class modelling Fraction, I want to throw an exception when divider is to be set to 0.
void Fraction::setQ(int q) {
if (q == 0){
throw new std::logic_error("Divider must not be null");
}else{
q_ = q;
}
}
And this code is tested with this block of code
BOOST_AUTO_TEST_CASE( NonZeroDivider ){
BOOST_CHECK_THROW(
f->setQ(0),
std::logic_error
);
}
But when boost should catch the exception, it doesn't and prints an error followed by a failure
unknown location(0): fatal error in "NonZeroDivider": unknown type
If you could help me on this one, I've tried BOOST_CHECK_EXCEPTION (with necessary editions) but no idea. Always the same behavior. Thanks!
Your code doesn't throw an exception (std::logic_error), it throws a pointer to a dynamically allocated exception (std::logic_error*); see throw new std::exception vs throw std::exception.
The fix is to remove the new keyword:
throw new std::logic_error("Divider must not be null");
~~~~

Catching exception: error: svd() failed to converge

I've written a function that uses Armadillo svd_econ function. I'm trying to handle the case where the svd fails to converge, because for some reason it doesn't abort the function in that case.
The error in question reads:
error: svd_econ(): failed to converge
Based on my reading of the SVD documentation, this should throw a std::runtime_error, and based on my reading of the Exceptions tutorial, I should be able to handle it like so:
arma::mat U, V;
arma::vec S;
try {
// aDat and subsetRows are previously defined
arma::svd_econ(U, S, V, aDat.rows(subsetRows), "right", "dc");
} catch (std::runtime_error e) {
std::cout << "Exception caught!" << std::endl;
// I want to abort, and return the error to R:
throw Rcpp::exception(e.what());
}
However, when I run this code with a case that gives me the error message above, I get a segfault. If I remove the try-catch block, the code keeps going, and throws an error further down when the code tries to use the results of the SVD.
I assume I'm just missing something obvious since I haven't formally learnt any C++
Looks good, I'd just try a few things:
a reference to the exception,
just error forwarding to R, not another throw(),
a default block with Rf_error()
So maybe (untested)
try {
arma::svd_econ(U, S, V, aDat.rows(subsetRows), "right", "dc");
} catch (std::runtime_error & e) {
std::cout << "Exception caught!" << std::endl;
forward_exception_to_r(e);
} default(...) {
Rf_error("Unknown exception");
}
but in essence you get all this for free via Rcpp Attributes as this is what the (automatically inserted) END_RCPP macro does --- see Section 2.7 of the Rcpp book for more details.
Edit But #mtall, in his comment, does what we should have done first: check the Armadillo docs. So you can simply check the return value. But you may want to try the suggested try/catch as well.

Throwing an error to main from a function called by another function

Let's say I have a function (mnHw) that calculates the mean of a vector (a vector of homework grades). This function throws a domain_error("Student did no homework") exception when the vector is empty. When I call mnHw from main, things are simple when I want to print out the error:
try
{
cout << mnHw(student.homework);
}
catch (domain_error e)
{
cout << e.what();
}
However, things are complicated if I only want to store the mean homework grade, instead of vector of all grades, for the student. In that case I call mnHw within the function that reads in the student information (readStudent), and put up a flag (-1) when no homework is entered:
try
{
student.finalGrade=mnHw(hwGrades);
}
catch (domain_error e)
{
student.finalGrade = -1;
}
Then, within main, I can do the following to recover the error:
if (allStudents[i].finalGrade == -1)
cout << "Student did no homework";
else
cout << allStudents[i].finalGrade;
Intuitively, though, this flag method seems less elegant than having the actual error message pass directly to main, at least for those cases when I want to display it from main (which is the case here). Is there some trick or technique I am missing that would directly give main access to e.what() from mnHw?
What is good practice?
Note I have full functions for each of these cases that I could post, but they seemed too long. Please let me know if I should have included them to make myself more clear. Also, please feel free to correct any other mistakes I’m making. I am just now learning C++ the right way, and want to be corrected as much as possible. <flame-retardant vest>
You can re-throw the exception catched (const domain_error* e){ throw e;}. Or better, you can create based on domain_error create another exception i.e., student_final_grade_exceptionand throw it.
EDIT:
Something like:
try
{
student.finalGrade=mnHw(hwGrades);
}
catch (domain_error& e)
{
student_final_grade_exception mean_excep;
mean_excep.addInfo("Error in calculation means...");
mean_excep.addInfo(e.what());
throw mean_excep;
}
And then, you prepare your main to catch student_final_grade_exception. Of course, there is a litle bit more work to create a new exception type, but it can make possible to get more info and let the functions to only what they suppose to do as were told.

c++ error handling return values error returned

I have a class that I have been given some error input handling for. It's a class that has been given it's own "extraction" operator and I've been asked to implement the code that I've been given. The problem I'm having is that the code I should use looks similar to this.
try {
while (some condition)
{....implemented code....}
} catch (runtime_error& e) {
cerr << e.what() << endl;
return 1;
}
The problem I am having compiling this is it doesn't seem to like the "return 1" value it gives me an error of:
invalid initialization of non-const reference of type ‘std::istream& {aka std::basic_istream<char>&}’ from an rvalue of type ‘int’
If I remove the return value it compiles straight but then the program fails to execute once it hits the area where it is trying to do the try statement. As mentioned the code I have there is the above is the example code we are supposed to implement so I assumed straight out of the box it would work. My condition for the while loop was
while (!std::cin.fail())
as I assumed I'd want to keep getting input until it fails for some reason. Why would the return values in this case be causing a problem?
Psychic debugging indicates:
your enclosing function has a signature of the form
std::istream& func_name(/*parameter list goes here*/)
Hence the compilation error