c++ exception handling pass by reference : thrown address is different from caught address?

Go To StackoverFlow.com

2

#include <iostream>
#include <exception>
using namespace std;


class myexception: public exception
{
  virtual const char* what() const throw()
  {
    return "My exception happened";
  }
};

int main ()
{
  try
  {
    myexception myex;
    printf("addr1:%x\n",&myex);
    throw myex;
  }
  catch (exception& e)
  {
    printf("addr2:%x\n",&e);
    cout << e.what() << endl;
  }
  return 0;
}

output of this program:

addr1:6d78c020
addr2:20a1080
My exception happened

Question: Do you see addr1 and addr2 are different, any idea why?

2012-04-04 00:38
by Sam J


6

When an exception is thrown, a copy is made. You're viewing the address of that copy.

(How could the handler's exception have the same address? When you threw, you exited the block containing the exception, so it ceased to exist. You can't access something that doesn't exist.)

2012-04-04 00:41
by GManNickG
copy is made only in case of pass-by-value right? , but here i have pasted the code which uses pass-by-reference - Sam J 2012-04-04 01:07
The throw is what makes the copy. You are catching a reference, but it is a reference to the copy that was made by throw - sparc_spread 2012-04-04 01:12
in c++ objects are created by invoking the corresponding constructor either it is default or copy constructor. Do u agree with me? in the above example, addr2 is a new object which was created by invoking the copy constructor. My question is, copy constructor is called only for the pass-by-value not for the pass-by-reference - Sam J 2012-04-04 01:23
@SamJ: You are missing the point. There are two different objects, the local object myex, which is in the stack of the function, the thrown object (the throw expression copies from the stack to a compiler defined location). Then if you catch by value a second copy is performed from the thrown object to the stack in the function that catches the exception. Note that the original exception must be kept in case you throw;, and that it cannot be myex because the stack was (potentially) unwound - David Rodríguez - dribeas 2012-04-04 01:27
@SamJ: That's not a question, that's a statement, and it's irrelevant to this situation, because you're not calling a function - Benjamin Lindley 2012-04-04 01:27
David R, Benjamin and sparc - i appreciate all your replies and all of them make sense. I have understood the concept after seeing the output at very first time in my computer. It appears you guys are answering the question after seeing the output of the program (i may be wrong) - Sam J 2012-04-04 01:54
@SamJ: Sorry for leaving my answer unattended, but the others have answer your questions with what I would say. No, I didn't rely on any output to determine the answer, it's just how it works. You say throw x;, the compiler copies x and then finds at where it should jump to to catch - GManNickG 2012-04-04 02:15
@SamJ: 15.1p3 A throw-expression copy-initializes (8.5) a temporary object, called the exception object [...] The temporary is an lvalue and is used to initialize the variable named in the matching handler That does not come from inspection of your results, but from the standard - David Rodríguez - dribeas 2012-04-04 02:51
GManNickG , i did not leave ur answer anattended. I have read ur answer too, in fact that was the first reply to my qtn. Any way thanks for all ur replies : - Sam J 2012-04-04 02:56
@SamJ: I said that I left it unattended. :) If you found an answer satisfactory, please accept it by clicking the check mark next to it - GManNickG 2012-04-04 03:00


1

This makes sense. The exception is copied when it is thrown, so that it can survive exiting the stack frame of its origin. Once that exception exits the {} block from which it originated, that stack frame is popped and all locals within it are gone. So it has to be copied.

2012-04-04 00:43
by sparc_spread
I understand that point, but my question is totally a different one from your answer. In the above program, you can see copy constructor is getting called(if you write a copy constructor then you can see it), which makes a separate copy of an obj. But actually copy constructor is called only for temp objects, such as pass-by-value - Sam J 2012-04-04 01:16
@SamJ: But actually copy constructor is called only for temp objects, such as pass-by-value. That's quite a statement, and an error. Copies can be made for other things than temp objects and in some cases temp objects will not be the result of copies nor be copied themselves - David Rodríguez - dribeas 2012-04-04 01:30