the behavior of g++ 3.3.1 exception

Discussion in 'C++' started by chenchang, Apr 19, 2004.

  1. chenchang

    chenchang Guest

    Hi, experts. i write a simple program to test EH in G++:

    void throwfunction()
    {
    throw "test";
    }

    class A
    {
    int i;
    public:
    A(int I):i(I){
    cout<<"---------------------------A:"<< i <<"-----------------------\n";
    }
    ~A()
    {
    cout<<"--------------------------~A:"<< i <<"-----------------------\n";
    }
    };

    int main(int ,char*)
    {
    A b(1);
    throwfunction();
    cout << "---after throw--------------\n";
    return 0;
    }

    According to TC++ 3rd(14.4.2),"resource acquisition is initialization". I
    think the result should be :
    -------------A:1---------------------
    ------------~A:1---------------------

    but the result is :
    -------------A:1---------------------
    //..there are some message for prompting to dump statck frame.

    what is the reason?

    In addition, i add try..catch.. in the main:

    int main(int ,char*)
    {
    try
    {
    A b(1);
    throwfunction();
    cout << "---after throw--------------\n";
    }
    catch(...)
    {
    throw;
    }
    return 0;
    }

    the result is:
    -------------A:1---------------------
    ------------~A:1---------------------
    //..there are some message for prompting to dump statck frame.

    it is the expected result, but why?
    chenchang, Apr 19, 2004
    #1
    1. Advertising

  2. chenchang wrote:

    > Hi, experts. i write a simple program to test EH in G++:
    >
    > void throwfunction()
    > {
    > throw "test";
    > }
    >
    > class A
    > {
    > int i;
    > public:
    > A(int I):i(I){
    > cout<<"---------------------------A:"<< i <<"-----------------------\n";


    If you are using 'cout', you must have some code you didn't bother to
    show us (otherwise your compiler would almost certainly have rejected
    the code). Please review FAQ 5.8.

    > }
    > ~A()
    > {
    > cout<<"--------------------------~A:"<< i <<"-----------------------\n";
    > }
    > };
    >
    > int main(int ,char*)


    This is not a legal definition of main(). The two arguments to main(),
    if used, must be of type 'int' and 'char**' (or equivalent) respectively.

    If you aren't using the arguments, just leave them out.

    > {
    > A b(1);
    > throwfunction();


    This throws an exception that you don't bother to catch. The result is a
    call to terminate(), which by default calls abort(). Whether or not
    stack unwinding occurs first is implementation-defined.

    > cout << "---after throw--------------\n";
    > return 0;
    > }
    >
    > According to TC++ 3rd(14.4.2),"resource acquisition is initialization". I
    > think the result should be :
    > -------------A:1---------------------
    > ------------~A:1---------------------


    That's a possible result.

    >
    > but the result is :
    > -------------A:1---------------------
    > //..there are some message for prompting to dump statck frame.


    I'm not sure if that's a strictly conforming result or not, but it seems
    reasonable.

    >
    > what is the reason?
    >
    > In addition, i add try..catch.. in the main:
    >
    > int main(int ,char*)


    Same problem as other main().

    > {
    > try
    > {
    > A b(1);
    > throwfunction();
    > cout << "---after throw--------------\n";
    > }
    > catch(...)
    > {
    > throw;


    This throws an exception that you don't bother to catch.

    > }
    > return 0;
    > }
    >
    > the result is:
    > -------------A:1---------------------
    > ------------~A:1---------------------
    > //..there are some message for prompting to dump statck frame.
    >
    > it is the expected result, but why?


    Why not?

    Maybe you should read a little bit more about exception handling. Only
    the things constructed during the 'try' block's execution are destructed
    as the result of an exception, and that's only required if the exception
    is caught. Anything automatic object constructed before the try block
    will be destructed as usual, at the end of the scope (or by an exception
    caught in an enclosing dynamic scope).

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 19, 2004
    #2
    1. Advertising

  3. chenchang

    chenchang Guest

    hi kevin:

    > Maybe you should read a little bit more about exception handling. Only
    > the things constructed during the 'try' block's execution are destructed
    > as the result of an exception, and that's only required if the exception
    > is caught. Anything automatic object constructed before the try block
    > will be destructed as usual, at the end of the scope (or by an exception
    > caught in an enclosing dynamic scope).


    Please refer to 14.4 The C++ Programming Language (Third Edition):
    "The Destructor will be called independently of whether the function is
    exited normally or exited an exception is thrown."

    it tells me that we need not declare an automatic object in try block!

    Sorry, I forgot to say that i am running G++ under the windows.


    "Kevin Goodsell" <> wrote in message
    news:mMKgc.150$...
    > chenchang wrote:
    >
    > > Hi, experts. i write a simple program to test EH in G++:
    > >
    > > void throwfunction()
    > > {
    > > throw "test";
    > > }
    > >
    > > class A
    > > {
    > > int i;
    > > public:
    > > A(int I):i(I){
    > > cout<<"---------------------------A:"<< i

    <<"-----------------------\n";
    >
    > If you are using 'cout', you must have some code you didn't bother to
    > show us (otherwise your compiler would almost certainly have rejected
    > the code). Please review FAQ 5.8.
    >
    > > }
    > > ~A()
    > > {
    > > cout<<"--------------------------~A:"<< i

    <<"-----------------------\n";
    > > }
    > > };
    > >
    > > int main(int ,char*)

    >
    > This is not a legal definition of main(). The two arguments to main(),
    > if used, must be of type 'int' and 'char**' (or equivalent) respectively.
    >
    > If you aren't using the arguments, just leave them out.
    >
    > > {
    > > A b(1);
    > > throwfunction();

    >
    > This throws an exception that you don't bother to catch. The result is a
    > call to terminate(), which by default calls abort(). Whether or not
    > stack unwinding occurs first is implementation-defined.
    >
    > > cout << "---after throw--------------\n";
    > > return 0;
    > > }
    > >
    > > According to TC++ 3rd(14.4.2),"resource acquisition is initialization".

    I
    > > think the result should be :
    > > -------------A:1---------------------
    > > ------------~A:1---------------------

    >
    > That's a possible result.
    >
    > >
    > > but the result is :
    > > -------------A:1---------------------
    > > //..there are some message for prompting to dump statck frame.

    >
    > I'm not sure if that's a strictly conforming result or not, but it seems
    > reasonable.
    >
    > >
    > > what is the reason?
    > >
    > > In addition, i add try..catch.. in the main:
    > >
    > > int main(int ,char*)

    >
    > Same problem as other main().
    >
    > > {
    > > try
    > > {
    > > A b(1);
    > > throwfunction();
    > > cout << "---after throw--------------\n";
    > > }
    > > catch(...)
    > > {
    > > throw;

    >
    > This throws an exception that you don't bother to catch.
    >
    > > }
    > > return 0;
    > > }
    > >
    > > the result is:
    > > -------------A:1---------------------
    > > ------------~A:1---------------------
    > > //..there are some message for prompting to dump statck frame.
    > >
    > > it is the expected result, but why?

    >
    > Why not?
    >
    > Maybe you should read a little bit more about exception handling. Only
    > the things constructed during the 'try' block's execution are destructed
    > as the result of an exception, and that's only required if the exception
    > is caught. Anything automatic object constructed before the try block
    > will be destructed as usual, at the end of the scope (or by an exception
    > caught in an enclosing dynamic scope).
    >
    > -Kevin
    > --
    > My email address is valid, but changes periodically.
    > To contact me please use the address from a recent posting.
    chenchang, Apr 19, 2004
    #3
  4. I think the behaviour you see is reasonable, because you don't flush
    the cout stream.

    Maybe
    cout << ".. ~A:i .." << flush;
    will give the result that you expected.

    Hans
    Hans-Christian Stadler, Apr 19, 2004
    #4
  5. chenchang

    chenchang Guest

    no, i got the same result even if i change '\n' to flush.

    "Hans-Christian Stadler" <> wrote in message
    news:c606n9$c4c$...
    > I think the behaviour you see is reasonable, because you don't flush
    > the cout stream.
    >
    > Maybe
    > cout << ".. ~A:i .." << flush;
    > will give the result that you expected.
    >
    > Hans
    chenchang, Apr 19, 2004
    #5
  6. chenchang

    tom_usenet Guest

    On Mon, 19 Apr 2004 16:02:13 +0800, "chenchang" <>
    wrote:

    >hi kevin:
    >
    >> Maybe you should read a little bit more about exception handling. Only
    >> the things constructed during the 'try' block's execution are destructed
    >> as the result of an exception, and that's only required if the exception
    >> is caught. Anything automatic object constructed before the try block
    >> will be destructed as usual, at the end of the scope (or by an exception
    >> caught in an enclosing dynamic scope).

    >
    >Please refer to 14.4 The C++ Programming Language (Third Edition):
    >"The Destructor will be called independently of whether the function is
    >exited normally or exited an exception is thrown."
    >
    >it tells me that we need not declare an automatic object in try block!


    Yes, but this only applies if the exception is caught eventually. If
    the exception propogates out of main, then "terminate" is called, and
    stack unwinding might not occur. The moral: never let any exceptions
    escape from main - to do so is a bug.

    Tom
    --
    C++ FAQ: http://www.parashift.com/c -faq-lite/
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    tom_usenet, Apr 19, 2004
    #6
  7. chenchang

    Rolf Magnus Guest

    chenchang wrote:

    >> Maybe you should read a little bit more about exception handling.
    >> Only the things constructed during the 'try' block's execution are
    >> destructed as the result of an exception, and that's only required if
    >> the exception is caught. Anything automatic object constructed before
    >> the try block will be destructed as usual, at the end of the scope
    >> (or by an exception caught in an enclosing dynamic scope).

    >
    > Please refer to 14.4 The C++ Programming Language (Third Edition):
    > "The Destructor will be called independently of whether the function
    > is exited normally or exited an exception is thrown."
    >
    > it tells me that we need not declare an automatic object in try block!


    Still, you don't catch the exception, so abort() is called. And abort()
    doesn't destroy local objects.
    Rolf Magnus, Apr 19, 2004
    #7
  8. chenchang

    Dave Moore Guest

    "chenchang" <> wrote in message news:<c6012v$660$99.com>...
    > hi kevin:
    >
    > > Maybe you should read a little bit more about exception handling. Only
    > > the things constructed during the 'try' block's execution are destructed
    > > as the result of an exception, and that's only required if the exception
    > > is caught. Anything automatic object constructed before the try block
    > > will be destructed as usual, at the end of the scope (or by an exception
    > > caught in an enclosing dynamic scope).

    >
    > Please refer to 14.4 The C++ Programming Language (Third Edition):
    > "The Destructor will be called independently of whether the function is
    > exited normally or exited an exception is thrown."
    >


    Please refer to the rest of chapter 14 in TC++PL, specifically 14.7
    .... there you will find exactly what Kevin already told you, that an
    uncaught exception generates implementation-defined behavior,
    particularly with regard to whether or not destructors are called.
    The phrase you quoted from 14.4 is only referring to objects that were
    in scope when the exception was thrown ... look at the preceeding
    example in the book.
    Dave Moore, Apr 19, 2004
    #8
  9. Hans-Christian Stadler wrote:

    > I think the behaviour you see is reasonable, because you don't flush
    > the cout stream.
    >
    > Maybe
    > cout << ".. ~A:i .." << flush;
    > will give the result that you expected.
    >


    Please quote the relevant context from the message you are replying to
    so that people reading your message know to what you are referring.

    Streams are flushed when they are destroyed, so explicit flushing isn't
    necessarily needed. However, exiting the program via abort() (via
    terminate(), via an uncaught exception) may not destroy existing
    objects. In fact, it may be required NOT to (I'd have to check to be
    sure). So this could feasibly be part of the problem, but a more general
    solution would be to not let exceptions go uncaught.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 19, 2004
    #9
  10. chenchang

    Dave Moore Guest

    (Dave Moore) wrote in message news:<>...
    > "chenchang" <> wrote in message news:<c6012v$660$99.com>...
    > > hi kevin:
    > >
    > > > Maybe you should read a little bit more about exception handling. Only
    > > > the things constructed during the 'try' block's execution are destructed
    > > > as the result of an exception, and that's only required if the exception
    > > > is caught. Anything automatic object constructed before the try block
    > > > will be destructed as usual, at the end of the scope (or by an exception
    > > > caught in an enclosing dynamic scope).

    > >
    > > Please refer to 14.4 The C++ Programming Language (Third Edition):
    > > "The Destructor will be called independently of whether the function is
    > > exited normally or exited an exception is thrown."
    > >

    >
    > Please refer to the rest of chapter 14 in TC++PL, specifically 14.7
    > ... there you will find exactly what Kevin already told you, that an
    > uncaught exception generates implementation-defined behavior,
    > particularly with regard to whether or not destructors are called.


    This is correct and relevant to OP's example ...

    > The phrase you quoted from 14.4 is only referring to objects that were
    > in scope when the exception was thrown ... look at the preceeding
    > example in the book.


    This is correct, but not relevant to OP's example .. no scoping issues
    exist in his code AFAICS .. its just the uncaught exception causing
    havoc .. sorry for any confusion
    Dave Moore, Apr 20, 2004
    #10
    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. jeff
    Replies:
    0
    Views:
    1,527
  2. Goran Sliskovic
    Replies:
    2
    Views:
    340
    Goran Sliskovic
    May 15, 2004
  3. Mantorok Redgormor
    Replies:
    70
    Views:
    1,750
    Dan Pop
    Feb 17, 2004
  4. none

    Odd Exception Behavior

    none, Feb 4, 2010, in forum: C++
    Replies:
    12
    Views:
    484
  5. Roy Smith
    Replies:
    6
    Views:
    158
    Chris Angelico
    Dec 3, 2012
Loading...

Share This Page