By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,407 Members | 2,842 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,407 IT Pros & Developers. It's quick & easy.

Why do i get uncaught exception and the program exits?

P: 8
Expand|Select|Wrap|Line Numbers
  1. class Error {
  2. Error(string err) { cout << err; }
  3. }
  4. void main()
  5. {
  6.   try {
  7.         throw string("exception");
  8.  }
  9.  catch(Error Err)
  10. {
  11. }
  12. return
  13. }
  14.  
my question is :
why i get uncaught exception and the program exits ,
even though i have a Error constructor that gets string ?
thanks
Nov 30 '10 #1
Share this Question
Share on Google+
15 Replies


Oralloy
Expert 100+
P: 983
danielo,

You must excuse me, but I have to point out that your code is completely untested.

It won't compile due to syntax errors at lines 3 and 12.

In addition, the main function is supposed to return an int.

Please fix the syntax errors, as well as the problem with main, and re-post your question.

Good Luck!
Oralloy
Nov 30 '10 #2

P: 7
Hi Danielo,

you have not coded to catch a string exception.
Or you have to code for generic catch.
Dec 1 '10 #3

P: 8
i understand , but i am catching Error class which contains constructor that accepts string.. so i dont understand why not
Dec 1 '10 #4

Oralloy
Expert 100+
P: 983
danielo,

in C++, you catch arbitrary types.

why do you think that you are supposed to catch an arbitrary Err object that has no formal existance in the specification?

there is a standard exception class in the std namespace, which standard many C++ exceptions and errors are derived from. however, its use is not mandatory, like java.lang.Throwable is in Java. all the std::exception class does is provide a structured method of building exceptions.

so...throw a type, catch a type. in your case, you're throwing a string, but catching an Err, so your exception handler will not catch it.

if you were hoping for implicit type conversion, it's not done as far as I know. there is implicit up-casting, however there is no run-time search over the possible conversion space for an arbitrarily thrown object. your entire example is 13 lines, however C++ is required to allow separate compilation and linking of modules, and still work consistently.

BTW, did you ever fix your errors and run the thing?
Dec 1 '10 #5

weaknessforcats
Expert Mod 5K+
P: 9,197
Also you do not catch objects. You catch references or pointers to objects. Otherwise, you create a new object in the catch block which isn't the one that was thrown:

Expand|Select|Wrap|Line Numbers
  1. catch (Error& Err)
  2. //etc...
Dec 1 '10 #6

Oralloy
Expert 100+
P: 983
@weaknessforcats,

Yep, that's the best way to go about it. However, I don't think that danielo understands the general concept of C++ error handling yet. I know that years ago, when try and catch were first introduced, that I used to throw strings (of the char* sort) on small projects, as they were quick and easy.

In fact, won't his example fail (assuming he throws an Err), because there is no appropriate copy constructor for his Err object? I don't have a C++ compiler handy, otherwise I'd test for my own benefit, thus my question.

Thanks,
Oralloy
Dec 1 '10 #7

100+
P: 207
I don't believe it will fail because the compiler will create a copy constructor for him.

It won't print out the error string because that piece of logic is only defined in the constructor.
Dec 1 '10 #8

Oralloy
Expert 100+
P: 983
@hype261,

Sometimes the compiler can create a copy constructor, and other times it can't. I don't remember the rules. However, when there are embedded classes/objects involved, there are problems. I do know that the old C standard where structs are copied bitwise does not apply in this case.

Still, as I noted in my comment, I don't have a C++ compiler handy to test against. If you do, will you build and run the test, please?

Thanks,
Oralloy
Dec 1 '10 #9

weaknessforcats
Expert Mod 5K+
P: 9,197
That's correct. C++ copies memberwise.

Therefore, the compiler copy constructor just calls the copy constructor of every member of your class.

You can supersede the compiler copy constructor by one of your own if you need more than is offered by the compiler version.
Dec 1 '10 #10

Oralloy
Expert 100+
P: 983
@weaknessforcats,

Which means that the compiler cannot generate an implicit copy constructor for a class, which contains a member that does not have an accessable copy constructor. Are there other restrictions?

In this case, everything's known, so the copy constructor is obviated.

However, the exception handling path knows nothing about object copies at run-time, so it can't implicitly instantiate copy constructors, even if it were appropriate.

Thus, my next question - does the C++ specification require that the copy constructors be be implicitly implemented for all non-reference-type exception handlers? (Yes, I do realize that invoking copy constructors for primitive types and pointers is moot. These, however are conceptually optimized away, anyway)
Dec 1 '10 #11

P: 8
i have a big application , i just gave an example of the situation , so i could understand the theory behind it , and for copy constructor , the compiler defines a default copy constructor which will activate the default copy constructor of each member , so no need for me to define one , and as for the exception class in stl (std..) , almost no body uses it because it is not good , i just want to understand why it is ok to catch base class of an exception and why it is illegal to implicit cast ( string to Err) since for example :

void func1(Error err);

and u make this call :
func1(string("that works!!!"));

this works while for exceptions it doesnt
thanks
Dec 1 '10 #12

100+
P: 207
Orally,

I built and ran the program which I believe was your question and it works just fine.

Expand|Select|Wrap|Line Numbers
  1. class Error 
  2. public:
  3.     Error(std::string err) { std::cout << err; } 
  4. }; 
  5.  
  6.  
  7.  
  8. int main()
  9. {
  10.     try
  11.     {
  12.         throw Error("Help");
  13.     }
  14.     catch(Error Err)
  15.     {
  16.  
  17.     }
  18.  
  19.     return 0;
  20. }
The output was Help and the compilier did generate the copy constructor for me.
Dec 1 '10 #13

P: 8
any idea why it wont catch it if you throw a string instead ?
Dec 1 '10 #14

Oralloy
Expert 100+
P: 983
danielo,

It won't catch a string, because the examples we currently have do not have exception handlers that catch string objects.

Of course, we can add an exception handler for strings if we want. Extending the example that @hype261 built:
Expand|Select|Wrap|Line Numbers
  1. class Error  
  2. {  
  3. public: 
  4.     Error(std::string err):str(err) { std::cout << err; }  
  5.     string str;
  6. };  
  7.  
  8.  
  9.  
  10. int main() 
  11.     try 
  12.     { 
  13.         throw string("Help");
  14.         throw Error("Help"); 
  15.     } 
  16.     catch(Error Err) 
  17.     { 
  18.       cout << "Caught Error: " << Err.str << endl;
  19.     } 
  20.     catch(string const &str) 
  21.     { 
  22.       cout << "Caught string: " << str << endl;
  23.     } 
  24.  
  25.     return 0; 
You'll have to add the appropriate includes, but this should work for you.
Dec 2 '10 #15

100+
P: 207
If I had to make a guess on why exceptions don't support implicit conversions is because it would be very difficult to do.

Implicit conversions for functions are realitively easy thing for a compiler to do. This function needs a Class A, but you gave it Class B, but A can be constructed from B. Now consider the following code example.

Expand|Select|Wrap|Line Numbers
  1.  
  2. class Error
  3. {
  4. public:
  5.      Error(string c){cout << c;};
  6. };
  7.  
  8. void c()
  9. {
  10.      throw string("HELP");
  11. }
  12.  
  13. void b()
  14. {
  15.      c();
  16. }
  17.  
  18. void a()
  19. {
  20.      b();
  21. }
  22.  
  23. int main()
  24. {
  25.      try
  26.      {
  27.           a();
  28.      }
  29.      catch(Error err)
  30.      {
  31.      }
  32. }
In this situation the compilier is going to have to go three functions deep to see you are going to throw a string and then do the implicit conversion. This example is really simple, consider what would happen if this was a real application. The compiler could be 50 functions deep across multiple source files.
Dec 2 '10 #16

Post your reply

Sign in to post your reply or Sign up for a free account.