exception handling - c++

#include <iostream>
using namespace std;
#include <exception>
void dis()
{
cout<<"terminate disabled "<< endl;
}
void display() throw(int,double)
{
if(0)
throw int();
if(0)
throw double();
if(1)
throw string();
}
int main()
{
set_unexpected(dis);
try
{
display();
}
catch(int)
{
cout<<"int "<< endl;
}
catch(double)
{
cout<<"double "<< endl;
}
catch(string)
{
cout<<"string "<< endl;
}
system("pause");
return 0;
}
now the output was
terminate disabled
and then the program terminated
but instead of set_unexpected when i wrote
set_terminate(dis);
the output was
terminate disabled
terminate disabled
why this dicrepancy?

So, it's not entirely clear what your original output was. I tried to clean it up as best as I could, but your quote tags make it unobvious.
In your code, if you use set_unexpected(dis), you should see:
terminate disabled
In your code if you use set_terminate(dis), you should see:
terminate disabled
In your code, if you use both set_unexpected(dis) and set_terminate(dis), you should see:
terminate disabled
terminate disabled
One way to get around this, is to have dis throw 0 as the last line. That would allow you to convert your exception to something that your function claims that it will throw.

Related

How to terminate an application when an error happnes?

I am using a Graphics Library called Irrlicht
at some point i have to write this code
if(!device){
//error code here`
}
i am not in the main function but want to close the application when this error happens
please keep in mind that I am a beginner so this question might sound dumb
i see some people do this:
int main(){
if(!device){
return 1;
}
return 0;
}
i am not in the main function and want to exit the application outside of the main function
The following example give you an idea about some of the possibilities.
You can simply copy and paste it and play around with it. Simply use only one line of the "termination actions" like throw or exit. If you don't have the try catch block in the main function, your application will also terminate because the exception will not be caught.
struct DeviceNotAvailable {};
struct SomeOtherError{};
void func()
{
void* device = nullptr; // only for debug
if (!device)
{
// use only ONE of the following lines:
throw( DeviceNotAvailable{} );
//throw( SomeOtherError{} );
//abort();
//exit(-1);
}
}
int main()
{
// if you remove the try and catch, your app will terminate if you
// throw somewhere
try
{
func();
}
catch(DeviceNotAvailable)
{
std::cerr << "No device available" << std::endl;
}
catch(SomeOtherError)
{
std::cerr << "Some other error" << std::endl;
}
std::cout << "normal termination" << std::endl;
}

C++ rethrow does not call custom terminate handler

I have used custom terminate handler which works fine if I call throw with a type or explicitly call terminate(), but if I use rethow i.e throw; , the custom terminate handler is not called, only default terminate handler is called causing the program to abort. Code confirms to C++03. Could anyone help me to find out the problem ? Thank you in advance
#include <iostream>
#include <exception>
using namespace std;
void myunexpected() {
cerr << "CUSTOM unexpected handler called ------ \n";
throw 0; // throws int (in exception-specification)
}
void myterminate () {
cerr << "CUSTOM terminate handler called ------ \n";
//abort(); // forces abnormal termination
exit(0);
}
void myfunction() throw (int) {
throw 'x'; // throws char (not in exception-specification)
}
int main(void) {
set_unexpected(myunexpected);
set_terminate(myterminate);
int a = 1;
try{
try {
myfunction();
}
catch (int) {
cerr << "caught int\n";
throw string("sree");
}
catch (...) { cerr << "caught some other exception type\n"; }
}
catch (string& s)
{
cerr << a << "caught STRING " << s << endl;
//throw 0; //ok --> implicitly calls terminate()-->myterminate
//terminate(); //ok --> explicitly calls terminate()-->myterminate
throw; //--------- Calls default throw Why ???
}
return 0;
}
OUTPUT
CUSTOM unexpected handler called ------
caught int
1caught STRING sree
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
--------------------------------
Process exited after 8.238 seconds with return value 255
Press any key to continue . . .

Why does it print out "abracadabra" and not "Timmy"?

This code throws an exception when I enter "Timmy" as the name. I'm really not sure of the mechanism but why does it print out "abracadabra" and not "Timmy". One thing I'm sure of though is that there is no magic going on here!
This is the short code
#include <iostream>
using namespace std;
#include <string>
#include <cstdlib>
string enterName();
void checkName(string);
int main()
{
string someName = "abracadabra";
try {
someName = enterName();
}
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
cout << "Name: "<<someName<<endl;
return 0;
}
string enterName()
{
string s;
cout<<"Enter a name: ";
cin >> s;
cout<<endl;
try {
checkName(s);
}
catch(const char* err) {
cout << "middle man says: "<<err <<endl;
throw "rtetfrer";
}
return s;
}
void checkName(string name)
{
if (name == "Timmy")
throw "Help, Timmy's been kidnapped by a giant squid!";
}
You are throwing an exception, so the function never returns:
void checkName(string name)
{
if (name == "Timmy")
//This throws an exception, so the function exits immediately
throw "Help, Timmy's been kidnapped by a giant squid!";
}
That exception is caught here:
try {
checkName(s);
}
catch(const char* err) {
//This will be the exception that timmy is caught
cout << "middle man says: "<<err <<endl;
//This will throw an exception and immediately exit the function
throw "rtetfrer";
}
//This will never be called
return s;
And the new exception will be caught here:
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
But since checkName never returned a value, somename will still be magic
enterName(); throws an exception before the assignment to someName is made. Hence someName retains its original value.
(In a little more detail: enterName() calls checkName(). checkName() throws an exception since name is "Timmy". enterName() throws "rtetfrer". Why not verify with your debugger?)
In order to assign a value to someName, c++ must first evaluate the expression on the left side. That is the result of the function enterName. Now during the execution of this function an exception is thrown. When this happens the execution jumps right to the catch clause(skipping the return clause of the function and then the assignment of someName to this return value), thus you never assign a different value to someName.
Use a debugger to follow the execution flow in an easier manner.

The sample code provided returns a random number, even after throwing an exception (code provided)

I have a sample code to modify and throw exception handling. The problem is even after I threw an exception, the code still returns a random 0. I have spent some time trying to figure out why I still have a 0 returned but I could not find the answer. Does anyone have an idea why the code behaves like this?
#include <stdexcept>
#include <iostream>
#include <string>
using namespace std;
struct myException_Product_Not_Found : exception
{
virtual const char* what() const throw() {
return "Product not found";
}
} myExcept_Prod_Not_Found;
int getProductID(int ids[], string names[], int numProducts, string target) {
for (int i=0; i<numProducts; i++) {
if(names[i] == target)
return ids[i];
}
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
}
// Sample code to test the getProductID function
int main() {
int productIds[] = {4,5,8,10,13};
string products[] = {"computer","flash drive","mouse","printer","camera"};
cout << getProductID(productIds, products, 5, "computer") << endl;
cout << getProductID(productIds, products, 5, "laptop") << endl;
cout << getProductID(productIds, products, 5, "printer") << endl;
return 0;
}
getProductID doesn't throw an exception. You catch the exception you do throw before getProductID has a chance to throw it. As such, you return ... well, nothing. The functions ends without you calling return.
If you had turned on your compiler's warnings* (as should should be doing), the compiler should warn with a message like control reaches end of non-void function. g++ appears to return zero in this instance, but returning zero is probably undefined behaviour.
If you want a function to throw an exception, don't catch the exception you've thrown inside of the function. Move the catch to the outside.
int getProductID(...) {
...
throw myExcept_Prod_Not_Found;
}
string product = "computer";
try {
cout << getProductID(productIds, products, 5, product) << endl;
} catch (exception& e) {
cout << "Can't find product id for " << product << ": " << e.what() << endl;
}
* — To turn on warnings in g++, -Wall is a good starting point. #Tomalak Geret'kal suggests -Wall -Wextra -std=c++98 -pedantic or -Wall -Wextra -std=c++0x -pedantic.
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
Here you're throwing an exception and then immediately catching it. The exception message is output to console and then execution of your function continues as normal... except you have no value to return.
So, the result of that function call is unspecified, and you're seeing some arbitrary rubbish from memory as well as invoking undefined behaviour.
Instead, just let the exception propogate right up the callstack by not catching it: it'll lead your program to terminate (possibly without actually unrolling, incidentally):
throw myExcept_Prod_Not_Found;

C++ Destructor Exception

I am a novice programmer working on some code for school. When the following code is executed, the word BAD is output. I do not understand why the letter C in the destructor is not output when the WriteLettersObj object is terminated.
// Lab 1
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class WriteLetters {
public:
WriteLetters();
void writeOneLetter();
~WriteLetters();
} WriteLettersObj;
WriteLetters::WriteLetters() {
cout << "B";
}
void WriteLetters::writeOneLetter() {
cout << "A";
}
WriteLetters::~WriteLetters() {
cout << "C" << endl;
}
int main() {
WriteLettersObj.writeOneLetter();
cout << "D";
getch();
return 0;
}
You are mixing iostream with non-ANSI conio.h.
Make this change:
// getch();
cin.get();
Hey presto, the C appears. At least on OS X it does. And Ubuntu.
Your program is live until you exit the main() with return 0 instruction. Since the WriteLettersObj is a global variable, it will be constructed before main() starts and destructed after main() finishes and not after getch().
To see your output getting printed, put getch() in the end of destructor.
I tried running your code without getch on linux and Mac and it runs just fine. #iammilind is right that you should move getch in the destructor.