why should throwing an exception by reference work

Discussion in 'C++' started by puzzlecracker, May 11, 2006.

  1. It shouldnt, since reference object is destroyed in the stack frame.
     
    puzzlecracker, May 11, 2006
    #1
    1. Advertising

  2. puzzlecracker

    Andre Kostur Guest

    On Wed, 10 May 2006 16:11:45 -0700, puzzlecracker wrote:

    > It shouldnt, since reference object is destroyed in the stack frame.


    Throwing an exception by reference? Or catching it?
     
    Andre Kostur, May 11, 2006
    #2
    1. Advertising

  3. puzzlecracker wrote:
    > It shouldnt, since reference object is destroyed in the stack frame.

    in this example

    void bar(){
    MyExcepton ex(); //MyException inherits from Excetpion
    Exception &exRef=ex;
    throw exRef;

    }

    void foo(){

    try{

    bar();
    }catch( Exception &ex){

    }catch(...){}
     
    puzzlecracker, May 11, 2006
    #3
  4. puzzlecracker

    Andre Kostur Guest

    On Wed, 10 May 2006 16:15:04 -0700, puzzlecracker wrote:

    > puzzlecracker wrote:
    >> It shouldnt, since reference object is destroyed in the stack frame.

    > in this example
    >
    > void bar(){
    > MyExcepton ex(); //MyException inherits from Excetpion
    > Exception &exRef=ex;
    > throw exRef;
    >
    > }
    >
    > void foo(){
    >
    > try{
    >
    > bar();
    > }catch( Exception &ex){
    >
    > }catch(...){}



    Ah... but when the exception is thrown... a copy is taken and put
    /somewhere/ (implementation-defined, I believe). So when you catch,
    you're getting a reference to that copied object.
     
    Andre Kostur, May 11, 2006
    #4
  5. puzzlecracker

    Andre Kostur Guest

    On Wed, 10 May 2006 23:17:08 +0000, Andre Kostur wrote:

    > On Wed, 10 May 2006 16:15:04 -0700, puzzlecracker wrote:
    >
    >> puzzlecracker wrote:
    >>> It shouldnt, since reference object is destroyed in the stack frame.

    >> in this example
    >>
    >> void bar(){
    >> MyExcepton ex(); //MyException inherits from Excetpion


    BTW, doesn't this declare a function named "ex", taking no parameters, and
    returning and object of type MyException, by value?
     
    Andre Kostur, May 11, 2006
    #5
  6. puzzlecracker

    Tomás Guest


    > void bar(){
    > MyExcepton ex(); //MyException inherits from Excetpion


    That's a very pretty function declaration you have there. It's exactly the
    same as writing:

    MyException ex(void);

    ReturnType FunctionName(ParameterList);

    What you want is:

    My Exception ex;

    > Exception &exRef=ex;
    > throw exRef;
    >
    > }
    >
    > void foo(){
    >
    > try{
    >
    > bar();
    > }catch( Exception &ex){



    You have an invalid reference here, because the object to which it refers
    has gone out of scope (i.e. has been destroyed).

    You could throw a reference if it's valid. For example:

    int global_var = 2;

    int main()
    {
    try
    {

    throw global_var;
    }
    catch (int &i)
    {
    i = 7;
    }
    }


    -Tomás
     
    Tomás, May 11, 2006
    #6
  7. puzzlecracker

    John Carson Guest

    "Tomás" <> wrote in message
    news:Jzu8g.9030$
    > "puzzlecracker" <> wrote in message
    > news:
    >> void bar(){
    >> MyExcepton ex(); //MyException inherits from Excetpion

    >
    > That's a very pretty function declaration you have there. It's
    > exactly the same as writing:
    >
    > MyException ex(void);
    >
    > ReturnType FunctionName(ParameterList);
    >
    > What you want is:
    >
    > My Exception ex;
    >
    >> Exception &exRef=ex;
    >> throw exRef;
    >>
    >> }
    >>
    >> void foo(){
    >>
    >> try{
    >>
    >> bar();
    >> }catch( Exception &ex){

    >
    >
    > You have an invalid reference here, because the object to which it
    > refers has gone out of scope (i.e. has been destroyed).


    I don't believe that is correct. Consider:

    #include <iostream>
    using namespace std;

    struct MyException
    {
    int a;
    };

    void bar()
    {
    MyException me = {4};
    MyException &meRef = me;
    throw meRef;
    }

    int main()
    {
    try
    {
    bar();
    }
    catch( MyException &me)
    {
    cout << "integer is " << me.a << '\n';
    }
    return 0;
    }

    This works as it should on VC++ 8 and compiles without warnings on both VC++
    8 and Comeau online.

    I believe the relevant section of the standard is 15.1/3:

    "A throw-expression initializes a temporary object, called the exception
    object, the type of which is determined by removing any top-level
    cv-qualifiers from the static type of the operand of throw and adjusting the
    type from "array of T" or "function returning T" to "pointer to T" or
    "pointer to function returning T", respectively. [Note: the temporary object
    created for a throw-expression that is a string literal is never of type
    char* or wchar_t*; that is, the special conversions for string literals from
    the types "array of const char" and "array of const wchar_t" to the types
    "pointer to char" and "pointer to wchar_t", respectively (4.2), are never
    applied to a throw-expression. ] The temporary is used to initialize the
    variable named in the matching handler (15.3)."

    On my reading, this means that the throw expression creates its own
    temporary, so it is not dependent on the one declared inside bar() in the
    code above (15.1/5 says that the creation of the temporary may be eliminated
    if it doesn't change the meaning of the program).

    It is of some interest to note that it apparently not necessary to make the
    argument to catch() const in spite of the fact that it is being initialized
    by a temporary.

    --
    John Carson
     
    John Carson, May 11, 2006
    #7
  8. John Carson wrote:
    > "Tomás" <> wrote in message
    > news:Jzu8g.9030$
    > > "puzzlecracker" <> wrote in message
    > > news:
    > >> void bar(){
    > >> MyExcepton ex(); //MyException inherits from Excetpion

    > >
    > > That's a very pretty function declaration you have there. It's
    > > exactly the same as writing:
    > >
    > > MyException ex(void);
    > >
    > > ReturnType FunctionName(ParameterList);
    > >
    > > What you want is:
    > >
    > > My Exception ex;
    > >
    > >> Exception &exRef=ex;
    > >> throw exRef;
    > >>
    > >> }
    > >>
    > >> void foo(){
    > >>
    > >> try{
    > >>
    > >> bar();
    > >> }catch( Exception &ex){

    > >
    > >
    > > You have an invalid reference here, because the object to which it
    > > refers has gone out of scope (i.e. has been destroyed).

    >
    > I don't believe that is correct. Consider:
    >
    > #include <iostream>
    > using namespace std;
    >
    > struct MyException
    > {
    > int a;
    > };
    >
    > void bar()
    > {
    > MyException me = {4};
    > MyException &meRef = me;
    > throw meRef;
    > }
    >
    > int main()
    > {
    > try
    > {
    > bar();
    > }
    > catch( MyException &me)
    > {
    > cout << "integer is " << me.a << '\n';
    > }
    > return 0;
    > }
    >
    > This works as it should on VC++ 8 and compiles without warnings on both VC++
    > 8 and Comeau online.
    >
    > I believe the relevant section of the standard is 15.1/3:
    >
    > "A throw-expression initializes a temporary object, called the exception
    > object, the type of which is determined by removing any top-level
    > cv-qualifiers from the static type of the operand of throw and adjusting the
    > type from "array of T" or "function returning T" to "pointer to T" or
    > "pointer to function returning T", respectively. [Note: the temporary object
    > created for a throw-expression that is a string literal is never of type
    > char* or wchar_t*; that is, the special conversions for string literals from
    > the types "array of const char" and "array of const wchar_t" to the types
    > "pointer to char" and "pointer to wchar_t", respectively (4.2), are never
    > applied to a throw-expression. ] The temporary is used to initialize the
    > variable named in the matching handler (15.3)."
    >
    > On my reading, this means that the throw expression creates its own
    > temporary, so it is not dependent on the one declared inside bar() in the
    > code above (15.1/5 says that the creation of the temporary may be eliminated
    > if it doesn't change the meaning of the program).
    >
    > It is of some interest to note that it apparently not necessary to make the
    > argument to catch() const in spite of the fact that it is being initialized
    > by a temporary.
    >
    > --
    > John Carson


    John - that does it, i guess.

    Reading Java Language specification
    (http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html) is
    much easier than c++ standard.... is that why c++ is dying?:)
     
    puzzlecracker, May 11, 2006
    #8
  9. puzzlecracker

    Zara Guest

    On 10 May 2006 18:38:54 -0700, "puzzlecracker" <>
    wrote:

    <....>
    >Reading Java Language specification
    >(http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html) is
    >much easier than c++ standard.... is that why c++ is dying?:)



    Ha, nice troll trap.

    Starting a thread, and the deiverging to some hot topic.

    Eat a carrot and feel fed, troll.

    Zara
     
    Zara, May 11, 2006
    #9
  10. puzzlecracker

    Earl Purple Guest

    John Carson wrote:
    > It is of some interest to note that it apparently not necessary to make the
    > argument to catch() const in spite of the fact that it is being initialized
    > by a temporary.
    >


    probably because there is no chance of an implicit conversion in a
    catch. It simply won' catch.

    void foo()
    {
    throw ("text");
    }

    void bar()
    {
    try
    {
    foo();
    }
    catch ( std::string & s ) // won't catch the exception
    {
    s.push_back( 'X' );
    }
    }

    And if you put const std::string & instead it still won't catch it.
     
    Earl Purple, May 11, 2006
    #10
  11. Earl Purple wrote:
    > John Carson wrote:
    > > It is of some interest to note that it apparently not necessary to make the
    > > argument to catch() const in spite of the fact that it is being initialized
    > > by a temporary.
    > >

    >
    > probably because there is no chance of an implicit conversion in a
    > catch. It simply won' catch.
    >
    > void foo()
    > {
    > throw ("text");
    > }
    >
    > void bar()
    > {
    > try
    > {
    > foo();
    > }
    > catch ( std::string & s ) // won't catch the exception
    > {
    > s.push_back( 'X' );
    > }
    > }
    >
    > And if you put const std::string & instead it still won't catch it.


    why not?

    is it because, you're throwing char *???
     
    puzzlecracker, May 11, 2006
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KJ
    Replies:
    5
    Views:
    396
    John Saunders
    Jul 25, 2003
  2. VincentWong
    Replies:
    1
    Views:
    604
    VincentWong
    Dec 29, 2003
  3. Stephan
    Replies:
    22
    Views:
    13,510
  4. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    991
    Mark Rae
    Dec 21, 2006
  5. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,258
    Smokey Grindel
    Dec 2, 2006
Loading...

Share This Page