1

Two Questions 1) What happens when an Object/variable is thrown to catch? Say for example,

int foo() {
   FILE *fp = ....;
   int dummy = 10;
   int *dummy_ptr = new int[10];
   throw 1;
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

In this situation, what happens here? A new variable created and then passed???

what if I use a pointer or a variable without reference

like catch(int *i) // or catch (int i)

Also, does all the variables/resources declared or initiated inside the scope has been freed/closed?

2) Also in the case of rethrow, if I plan to rethrow with a reference, the second catch gets a new variable, if I i rethrow with without reference (i.e) by value, then the changes done in the intermediate throw is not affected....

int goo() {
    throw 2;
}

int foo() {
   try{
      goo();
   } catch(int &i) { // (or) catch(int i) // i is not changing in the next line.
      i = 2;
      throw;
   }
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

OUTPUT: catch(int &i) // prints 2 catch(int i) // prints 1

From my judgment,

What I think is, as long as it is reference, the value gets affected, if its 'pass by value' in the intermediate step. it still throws the original object to the second catch.

(i.e) the control flow for the variable is really not throw the intermediate catch.....

howtechstuffworks
  • 1,824
  • 4
  • 29
  • 46

3 Answers3

5

In this situation, what happens here? A new variable created and then passed?

Yes; when you throw an object it's created somewhere, and then destroyed once the exception has been handled (that is, after leaving the catch block without rethrowing).

what if I use a pointer or a variable without reference? Also in the case of rethrow...

If you catch by value then you'll get a copy of that object - if you rethrow the exception, then the next handler will get a new copy of the original, and won't see any changes you might have made. Catching by reference will give you a reference to the thrown object - if you rethrow, then the next handler will see any changes you made. You can't catch the object by pointer - you'll only catch a pointer if a pointer was thrown.

Also, does all the variables declared or initiated inside the scope has been closed?

When an exception is thrown all automatic variables are destroyed, in the scope of the throw and all enclosing scopes until the handler is reached. Dynamically allocated variables (such as your new int[10]) are not deleted, and arbitrary clean-up functions like fclose are certainly not called for FILE* variables, unless they are managed by a scope-based object such as a smart pointer.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Yeah in the case of pointer, that's what I meant, throwing a pointer, I guess it will handle, the same way it handles references...... makes sense now, didn't think through before. – howtechstuffworks Feb 22 '12 at 17:18
  • @howtechstuffworks: Throwing pointers is usually a bad idea - you certainly need to be careful what it points to. You shouldn't throw a pointer to an automatic object, since it might be destroyed before it's caught; and you shouldn't throw a pointer to a new dynamic object, since that would leak if the catcher forgets to delete it (which can't be done if it ends up in `catch(...)`). It's usually best to throw an object. – Mike Seymour Feb 22 '12 at 17:22
  • "when an exception is thrown all automatic variables are destroyed" Correct, but nothing else is destroyed, so your "Yes" should be "No" if the question is whether the memory allocated by `new int[10]` will be freed. –  Feb 22 '12 at 17:23
  • @Mike: yeah, I never 'thrown' a pointer in my life.... Just curious on how the thing is going to work, in pointers.... uhhh, but if its the case..... what happens if I receive a reference and try to throw that one...... like foo(int &a) {throw a; }, this one is going to suffer damage as far as the pointers.... – howtechstuffworks Feb 22 '12 at 17:26
  • @hvd: Oh yes, I didn't spot the `new`. – Mike Seymour Feb 22 '12 at 17:28
  • @hvd: why the double standards between stack & heap.... After all, I am asking the compiler to take care of something that has been created there..... its not something thats been passed as argument??? – howtechstuffworks Feb 22 '12 at 17:29
  • 1
    @howtechstuffworks: That's how automatic and dynamic storage work. Automatic objects are destroyed when they go out of scope; dynamic objects are *only* destroyed when you do it explicitly. That's why you should always use [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) techniques to deal with dynamic resources. – Mike Seymour Feb 22 '12 at 17:33
  • ^ yeah +1, thats the reason for heap... but I don't see a reason why we need to persist with something that has been created in a failed function..... or am I not exactly using exception handling as it is intended to??? – howtechstuffworks Feb 22 '12 at 17:36
  • 1
    @howtechstuffworks: I don't quite follow you - do you mean you don't see why the dynamic object shouldn't be deleted? That's because C++ doesn't have garbage collection - nothing is ever deleted unless something does it explicitly. If you need to mix dynamic objects and exceptions, then you really, really need RAII. (Without exceptions, it's just a very good idea). – Mike Seymour Feb 22 '12 at 17:49
  • Actually I understand what you saying..... I was talking about a different situation and quite didn't consider other cases.... I understand why we use heaps, what I was thinking was, if a function is a failed function and its doesn't make much sense to me, to continue with variables, it doesn't matter if its heap or stack... In another way.... in my coding I initialized dummy pointer with array size of 10. If my function is failed then I don't see a reason, why I use it in someother function(for eg,main function). Usually, we return the pointer via return_variable... thats not going to happen. – howtechstuffworks Feb 22 '12 at 18:31
  • +1 for RAII, if anyone have some online resources for RAII, please send me link... Thanks – howtechstuffworks Feb 22 '12 at 18:33
0

Yes, when an exception is thrown all automatic variables are destroyed, in the scope of the throw and all enclosing scopes until the handler is reached.

One note on this, your memory in dummy_ptr* will not be deallocated, and your FILE pointer fp* will not be closed.

Ivan Kosarev
  • 304
  • 1
  • 7
Smittii
  • 187
  • 1
  • 10
  • makes sense, but I don't think its justifiable...... Because, if something is created on heap/stack and somethinggoes wrong after that, whats the purpose of not removing it???? In stack it works fine, but not in heap..... What makes a heap different here??? and after all its been created here, not something passed from some other place......... – howtechstuffworks Feb 22 '12 at 17:23
  • @howtechstuffworks The reason you create things on the heap is because you want them to persist after you leave the function. – James Kanze Feb 22 '12 at 17:31
  • ^ yeah James, thats the general sense....... but whats the point if your function fails...... dont you want everything to rollback??? – howtechstuffworks Feb 22 '12 at 17:34
0

I don't think you can call it a variable; it doesn't have a name. But a new object of type int is created, in an unspecified place determined by the implementation. When you catch by reference, the reference is bound to that hidden object. And when you fall off the end of the catch block, or leave the catch block by any means other than rethrowing the same exception, the object is “freed”.

James Kanze
  • 150,581
  • 18
  • 184
  • 329