Handle C++ exception and structured exception together

Discussion in 'C++' started by George2, Jan 24, 2008.

  1. George2

    George2 Guest

    Hello everyone,


    I am learning set_se_translator, and there are some good resources
    about how to translate structured exception into C++ exception, like,

    http://www.codeproject.com/KB/cpp/seexception.aspx

    1.

    What makes me confused is, when we are talking about translate, it
    means both structured exception and C++ exception may occur in a C++
    program, right?

    2.

    But from build option, we can select either /EHa or /EHsc, means we
    can only select one type of exception, either asynchronous
    (structured) or synchronous (C++ exception).

    (1) and (2) are conflict?


    thanks in advance,
    George
    George2, Jan 24, 2008
    #1
    1. Advertising

  2. George2

    anon Guest

    George2 wrote:
    > Hello everyone,
    >
    >
    > I am learning set_se_translator, and there are some good resources
    > about how to translate structured exception into C++ exception, like,
    >
    > http://www.codeproject.com/KB/cpp/seexception.aspx
    >


    LOL
    this code looks like coming from a clown:

    catch(CSeException *e)
    {
    e->ReportError(MB_OK | MB_ICONSTOP);
    e->Delete();
    }

    Wondering what they do in Delete() method. Hope not "delete this"

    BTW http://www.parashift.com/c -faq-lite/exceptions.html#faq-17.7 is
    missing that the best way is to catch const reference
    anon, Jan 24, 2008
    #2
    1. Advertising

  3. George2

    Pavel Guest

    George2 wrote:
    > Hello everyone,
    >
    >
    > I am learning set_se_translator, and there are some good resources
    > about how to translate structured exception into C++ exception, like,
    >
    > http://www.codeproject.com/KB/cpp/seexception.aspx
    >
    > 1.
    >
    > What makes me confused is, when we are talking about translate, it
    > means both structured exception and C++ exception may occur in a C++
    > program, right?
    >
    > 2.
    >
    > But from build option, we can select either /EHa or /EHsc, means we
    > can only select one type of exception, either asynchronous
    > (structured) or synchronous (C++ exception).
    >
    > (1) and (2) are conflict?
    >
    >
    > thanks in advance,
    > George

    My understanding is that you need to use /EHsc, because your code will
    catch C++ exceptions; the code that throws structured exceptions has
    already been compiled into the libraries your code uses. Did not try it
    myself though.

    -Pavel
    Pavel, Jan 25, 2008
    #3
  4. George2

    Pavel Guest

    anon wrote:
    > George2 wrote:
    >> Hello everyone,
    >>
    >>
    >> I am learning set_se_translator, and there are some good resources
    >> about how to translate structured exception into C++ exception, like,
    >>
    >> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>

    >
    > LOL
    > this code looks like coming from a clown:
    >
    > catch(CSeException *e)
    > {
    > e->ReportError(MB_OK | MB_ICONSTOP);
    > e->Delete();
    > }
    >
    > Wondering what they do in Delete() method. Hope not "delete this"


    I thought "delete this" was not bad-bad, although certainly not ideal.
    Sometimes there is no good alternative to at least indirect "delete
    this" or its equivalent ... or I simply do not know one. Do you?
    Pavel, Jan 25, 2008
    #4
  5. * Pavel:
    > anon wrote:
    >> George2 wrote:
    >>> Hello everyone,
    >>>
    >>>
    >>> I am learning set_se_translator, and there are some good resources
    >>> about how to translate structured exception into C++ exception, like,
    >>>
    >>> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>>

    >>
    >> LOL
    >> this code looks like coming from a clown:
    >>
    >> catch(CSeException *e)
    >> {
    >> e->ReportError(MB_OK | MB_ICONSTOP);
    >> e->Delete();
    >> }
    >>
    >> Wondering what they do in Delete() method. Hope not "delete this"

    >
    > I thought "delete this" was not bad-bad, although certainly not ideal.
    > Sometimes there is no good alternative to at least indirect "delete
    > this" or its equivalent ... or I simply do not know one. Do you?


    The problem is mostly that with an exception there's no designated
    "owner" that's responsible for deleting. And with a catch(...) you have
    a memory leak. The code above is based on MFC exceptions, which were a
    pre-standard hack to use exceptions in a language implementation that
    didn't support exceptions.

    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 25, 2008
    #5
  6. George2

    anon Guest

    Pavel wrote:
    > anon wrote:
    >> George2 wrote:
    >>> Hello everyone,
    >>>
    >>>
    >>> I am learning set_se_translator, and there are some good resources
    >>> about how to translate structured exception into C++ exception, like,
    >>>
    >>> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>>

    >>
    >> LOL
    >> this code looks like coming from a clown:
    >>
    >> catch(CSeException *e)
    >> {
    >> e->ReportError(MB_OK | MB_ICONSTOP);
    >> e->Delete();
    >> }
    >>
    >> Wondering what they do in Delete() method. Hope not "delete this"

    >
    > I thought "delete this" was not bad-bad, although certainly not ideal.
    > Sometimes there is no good alternative to at least indirect "delete
    > this" or its equivalent ... or I simply do not know one. Do you?


    http://www.parashift.com/c -faq-lite/freestore-mgmt.html#faq-16.15

    Do you have an example where "delete this" would be good? Or at least
    not bad?
    anon, Jan 25, 2008
    #6
  7. George2

    Pavel Guest

    Pavel wrote:
    > George2 wrote:
    >> Hello everyone,
    >>
    >>
    >> I am learning set_se_translator, and there are some good resources
    >> about how to translate structured exception into C++ exception, like,
    >>
    >> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>
    >> 1.
    >>
    >> What makes me confused is, when we are talking about translate, it
    >> means both structured exception and C++ exception may occur in a C++
    >> program, right?
    >>

    ...

    >>
    >> thanks in advance,
    >> George

    > My understanding is that you need to use /EHsc, because your code will
    > catch C++ exceptions; the code that throws structured exceptions has
    > already been compiled into the libraries your code uses. Did not try it
    > myself though.
    >
    > -Pavel

    Sorry, my gut feeling was wrong, this time documentation says otherwise:
    Use /EHa instead of /EHsc when using _set_se_translator.
    see http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.71).aspx

    -Pavel
    Pavel, Jan 26, 2008
    #7
  8. George2

    Pavel Guest

    Alf P. Steinbach wrote:
    > * Pavel:
    >> anon wrote:
    >>> George2 wrote:
    >>>> Hello everyone,
    >>>>
    >>>>
    >>>> I am learning set_se_translator, and there are some good resources
    >>>> about how to translate structured exception into C++ exception, like,
    >>>>
    >>>> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>>>
    >>>
    >>> LOL
    >>> this code looks like coming from a clown:
    >>>
    >>> catch(CSeException *e)
    >>> {
    >>> e->ReportError(MB_OK | MB_ICONSTOP);
    >>> e->Delete();
    >>> }
    >>>
    >>> Wondering what they do in Delete() method. Hope not "delete this"

    >>
    >> I thought "delete this" was not bad-bad, although certainly not ideal.
    >> Sometimes there is no good alternative to at least indirect "delete
    >> this" or its equivalent ... or I simply do not know one. Do you?

    >
    > The problem is mostly that with an exception there's no designated
    > "owner" that's responsible for deleting. And with a catch(...) you have
    > a memory leak. The code above is based on MFC exceptions, which were a
    > pre-standard hack to use exceptions in a language implementation that
    > didn't support exceptions.
    >
    > Cheers, & hth.,
    >
    > - Alf
    >

    I agree, in general catch(...) does not work for throwing pointers; but
    in the example in question the structured exceptions are all inherited
    from CSeException so they can be safely caught and deleted if needed.
    Structured exceptions targeted C language, with no automatic stack
    unwinding, kind of glorified setjmp()/longjmp() so throwing pointers and
    deleting memory in the handler seems to be a more or less precise
    mapping of the concept into the standard C++ syntax.

    I believe the "clown" pan was aimed at "delete this" idea though.

    -Pavel
    Pavel, Jan 26, 2008
    #8
  9. * Pavel:
    > Alf P. Steinbach wrote:
    >> * Pavel:
    >>> anon wrote:
    >>>> George2 wrote:
    >>>>> Hello everyone,
    >>>>>
    >>>>>
    >>>>> I am learning set_se_translator, and there are some good resources
    >>>>> about how to translate structured exception into C++ exception, like,
    >>>>>
    >>>>> http://www.codeproject.com/KB/cpp/seexception.aspx
    >>>>>
    >>>>
    >>>> LOL
    >>>> this code looks like coming from a clown:
    >>>>
    >>>> catch(CSeException *e)
    >>>> {
    >>>> e->ReportError(MB_OK | MB_ICONSTOP);
    >>>> e->Delete();
    >>>> }
    >>>>
    >>>> Wondering what they do in Delete() method. Hope not "delete this"
    >>>
    >>> I thought "delete this" was not bad-bad, although certainly not
    >>> ideal. Sometimes there is no good alternative to at least indirect
    >>> "delete this" or its equivalent ... or I simply do not know one. Do you?

    >>
    >> The problem is mostly that with an exception there's no designated
    >> "owner" that's responsible for deleting. And with a catch(...) you
    >> have a memory leak. The code above is based on MFC exceptions, which
    >> were a pre-standard hack to use exceptions in a language
    >> implementation that didn't support exceptions.
    >>
    >> Cheers, & hth.,
    >>
    >> - Alf
    >>

    > I agree, in general catch(...) does not work for throwing pointers; but
    > in the example in question the structured exceptions are all inherited
    > from CSeException so they can be safely caught and deleted if needed.
    > Structured exceptions targeted C language, with no automatic stack
    > unwinding, kind of glorified setjmp()/longjmp() so throwing pointers and
    > deleting memory in the handler seems to be a more or less precise
    > mapping of the concept into the standard C++ syntax.
    >
    > I believe the "clown" pan was aimed at "delete this" idea though.


    * C++: I believe the "clown" comment was aimed at throwing pointers to
    dynamically allocated objects. It's a recipe for disaster, because of
    the lack of designated owner and possibility of "catch(...)". Using
    "delete this", on the other hand, is a normal way to do destruction in
    many situations, nothing wrong with that, although it is a power tool
    that can be dangerous in untrained hands.

    * Windows: structured exception handling (SEH) is an operation system
    API way to communicate failure that targets no specific language, but
    does require language support. Most of it is undocumented. As I recall
    Matt Pietrik (not sure of speling) wrote a series of articles going into
    depth of the undocumented aspects, including typical language support.

    * MFC exceptions (MFC is an old C++ GUI framework from Microsoft):
    throwing pointers had, as far as I know, nothing to do with SEH, and
    these exceptions were not targeted at C, since MFC was and is a C++
    class framework. Rather, it probably had to do with this exception
    handling being implemented via macros and nifty hacking, before C++
    exception handling became available. Keep in mind that MFC predates the
    C++ standard, and that C++ exception handling wasn't frozen until late
    in the standardization process.

    The pre-standard macro way (example lifted from [1]):

    TRY
    {
    // Do something to throw an exception.
    AfxThrowUserException();
    }
    CATCH(CException, e)
    {
    if (m_bPassExceptionsUp)
    THROW_LAST();

    if (m_bReturnFromThisFunction)
    return;

    // Not necessary to delete the exception e.
    }
    END_CATCH

    Using standard C++ exception handling the cleanup that was hidden in the
    macros must be done manually:

    try
    {
    // Do something to throw an exception.
    AfxThrowUserException();
    }
    catch(CException* e)
    {
    if (m_bPassExceptionsUp)
    throw;

    if (m_bThrowDifferentException)
    {
    e->Delete();
    throw new CMyOtherException;
    }

    if (m_bReturnFromThisFunction)
    {
    e->Delete();
    return;
    }

    e->Delete();
    }

    Of course, this mess is on its own a good reason not to use MFC... ;-)

    Cheers, & hth.,

    - Alf


    Notes:
    [1] <url: http://msdn2.microsoft.com/en-us/library/19z28s5c.aspx>

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 26, 2008
    #9
  10. George2

    Pavel Guest

    anon wrote:
    > Pavel wrote:
    >> anon wrote:
    >>> George2 wrote:
    >>>> Hello everyone,
    >>>>

    ....
    >>>
    >>> LOL
    >>> this code looks like coming from a clown:
    >>>
    >>> catch(CSeException *e)
    >>> {
    >>> e->ReportError(MB_OK | MB_ICONSTOP);
    >>> e->Delete();
    >>> }
    >>>
    >>> Wondering what they do in Delete() method. Hope not "delete this"

    >>
    >> I thought "delete this" was not bad-bad, although certainly not ideal.
    >> Sometimes there is no good alternative to at least indirect "delete
    >> this" or its equivalent ... or I simply do not know one. Do you?

    >
    > http://www.parashift.com/c -faq-lite/freestore-mgmt.html#faq-16.15

    Sure, and the synposis of the answer to this FAQ is (quoting):
    "As long as you're careful, it's OK for an object to commit suicide
    (delete this)."

    > Do you have an example where "delete this" would be good? Or at least
    > not bad?

    virtual Delete() or destroy() function is one of the OK ways to free the
    object's memory (after freeing all other resources owned by the object,
    if any) when the object knows how to free the memory it occupies in most
    general case. When the memory is to be freed via delete, the function
    has to call delete.

    The technique has its pros and contras (IMHO mostly pros) when compared
    with the alternatives I know. Do you know a clearly superior alternative?

    -Pavel
    Pavel, Jan 26, 2008
    #10
  11. George2

    Pavel Guest

    ....
    >>>>> Wondering what they do in Delete() method. Hope not "delete this"

    ....
    >> I agree, in general catch(...) does not work for throwing pointers;
    >> but in the example in question the structured exceptions are all
    >> inherited from CSeException so they can be safely caught and deleted
    >> if needed. Structured exceptions targeted C language, with no
    >> automatic stack unwinding, kind of glorified setjmp()/longjmp() so
    >> throwing pointers and deleting memory in the handler seems to be a
    >> more or less precise mapping of the concept into the standard C++ syntax.
    >>
    >> I believe the "clown" pan was aimed at "delete this" idea though.

    >
    > * C++: I believe the "clown" comment was aimed at throwing pointers to
    > dynamically allocated objects.

    I disagree. "delete this" fragment was brought up by the commenter (see
    above), it was not in the original post.

    It's a recipe for disaster, because of
    > the lack of designated owner and possibility of "catch(...)". U

    In general, it is a recipe for a memory leak (whether a memory leak is
    always and patently a disaster is a different matter). In particular,
    when only structured exceptions (thrown by the underlying C API we do
    not control) are processed by throwing a pointer to an exception and all
    such exceptions have a common base class (in the example, CSeException),
    it seems acceptable to me (and will not create a memory leak). I am just
    trying to keep in mind the original problem: processing Windows
    sructured exceptions in C++ code.

    > "delete this", on the other hand, is a normal way to do destruction in
    > many situations, nothing wrong with that, although it is a power tool
    > that can be dangerous in untrained hands.

    Completely agree.

    > * Windows: structured exception handling (SEH) is an operation system
    > API way to communicate failure that targets no specific language, but
    > does require language support. Most of it is undocumented. As I recall
    > Matt Pietrik (not sure of speling) wrote a series of articles going into
    > depth of the undocumented aspects, including typical language support.

    Well, it is documented in the enough details to catch them in C. "No
    specific language" is correct for the exception client but not for the
    code that raises exception (it is C API, after all).

    Language support (beyond setjmp()/longjmp() support which would
    introduce platform dependency anyway, by C standard) was not really
    required to solve the problem, it was just usual old Microsoft's way of
    presenting their facilities in the most nonstandard way possible.

    > * MFC exceptions (MFC is an old C++ GUI framework from Microsoft):
    > throwing pointers had, as far as I know, nothing to do with SEH, and
    > these exceptions were not targeted at C, since MFC was and is a C++
    > class framework.

    Well that's where I would partly disagree. What you are saying is a
    possibility but why exactly Microsoft introduced this "MFC standard way"
    of throwing will probably stay unknown forever. Theoretically it is
    possible it did not have anything to do with SEH but it is obvious to me
    that unconditionally leaving the destruction of the exception
    information up to the exception handler is so consistent with the
    structured exceptions and old C ways (again, I heard your "no specific
    language" but ? was the primary API target and implementation language
    (with some assembler) so I would not bet much on that.

    But it is all misses the point (almost). The reason why I mentioned the
    MFC exception is because the code in the question took MFC base
    exception to handle Windows structured exceptions (even though the did
    not have to do it):

    class CSeException : public CException
    {
    ....

    and then the followed the regular MFC practice of throwing the pointers.
    The resulting code and suggested framework seem reasonably save to me as
    long as the users will use MFC conventions consistently (which they will
    have trouble not to do anyway as the solution introduces dependencies on
    MFC).

    ....
    > Of course, this mess is on its own a good reason not to use MFC... ;-)

    Agree, I never liked MFC myself. Even now I use C API on Windows --
    "When in Rome .." -- and AFAIK "Romans" do not use MFC for their killer
    apps -- or maybe they do now but before they did not.

    -Pavel
    Pavel, Jan 26, 2008
    #11
  12. * Pavel:
    > ...
    >>>>>> Wondering what they do in Delete() method. Hope not "delete this"

    > ...
    >>> I agree, in general catch(...) does not work for throwing pointers;
    >>> but in the example in question the structured exceptions are all
    >>> inherited from CSeException so they can be safely caught and deleted
    >>> if needed. Structured exceptions targeted C language, with no
    >>> automatic stack unwinding, kind of glorified setjmp()/longjmp() so
    >>> throwing pointers and deleting memory in the handler seems to be a
    >>> more or less precise mapping of the concept into the standard C++
    >>> syntax.
    >>>
    >>> I believe the "clown" pan was aimed at "delete this" idea though.

    >>
    >> * C++: I believe the "clown" comment was aimed at throwing pointers to
    >> dynamically allocated objects.

    > I disagree. "delete this" fragment was brought up by the commenter (see
    > above), it was not in the original post.
    >
    > It's a recipe for disaster, because of
    >> the lack of designated owner and possibility of "catch(...)". U

    > In general, it is a recipe for a memory leak (whether a memory leak is
    > always and patently a disaster is a different matter).


    It can easily lead to memory leaks, yes, and it can also easily lead to
    double destruction. Both are generally disasters. Although possibly
    not immediate disasters in the sense of an immediate program crash.


    > In particular,
    > when only structured exceptions (thrown by the underlying C API we do
    > not control) are processed by throwing a pointer to an exception and all
    > such exceptions have a common base class (in the example, CSeException),
    > it seems acceptable to me (and will not create a memory leak).


    First, since the code is using MFC exceptions it's not only SEH
    exceptions that are handled that way.

    Second, the conclusion "and will not create a memory leak" does not follow.

    On the contrary, since SEH exceptions can be asynchronous and can occur
    at any point (e.g. for dereferencing a nullpointer), translating them to
    C++ throwing of pointer to dynamically allocated exception object is
    very likely to result in a memory leak, unless all the code is under
    your control -- and even then...


    > I am just
    > trying to keep in mind the original problem: processing Windows
    > sructured exceptions in C++ code.


    Not a big deal, except it's necessarily C++ implementation-specific, in
    particular possibly requiring special compiler switches.



    >> "delete this", on the other hand, is a normal way to do destruction in
    >> many situations, nothing wrong with that, although it is a power tool
    >> that can be dangerous in untrained hands.

    > Completely agree.
    >
    >> * Windows: structured exception handling (SEH) is an operation system
    >> API way to communicate failure that targets no specific language, but
    >> does require language support. Most of it is undocumented. As I
    >> recall Matt Pietrik (not sure of speling) wrote a series of articles
    >> going into depth of the undocumented aspects, including typical
    >> language support.

    > Well, it is documented in the enough details to catch them in C.


    No, the SEH documentation is for Microsoft's C and C++ language extensions.


    > "No
    > specific language" is correct for the exception client but not for the
    > code that raises exception (it is C API, after all).


    No, it's not a C API.

    The documented language extensions are for C and C++. However, it's not
    documented how they work together with the (operating system) API, i.e.
    how these extensions are implemented or what you'd do without them. At
    least, it didn't use to be documented, and I haven't checked lately.

    However, that's largely off-topic in clc++.


    > Language support (beyond setjmp()/longjmp() support which would
    > introduce platform dependency anyway, by C standard) was not really
    > required to solve the problem, it was just usual old Microsoft's way of
    > presenting their facilities in the most nonstandard way possible.
    >
    >> * MFC exceptions (MFC is an old C++ GUI framework from Microsoft):
    >> throwing pointers had, as far as I know, nothing to do with SEH, and
    >> these exceptions were not targeted at C, since MFC was and is a C++
    >> class framework.

    > Well that's where I would partly disagree. What you are saying is a
    > possibility but why exactly Microsoft introduced this "MFC standard way"
    > of throwing will probably stay unknown forever. Theoretically it is
    > possible it did not have anything to do with SEH but it is obvious to me
    > that unconditionally leaving the destruction of the exception
    > information up to the exception handler is so consistent with the
    > structured exceptions and old C ways (again, I heard your "no specific
    > language" but ? was the primary API target and implementation language
    > (with some assembler) so I would not bet much on that.
    >
    > But it is all misses the point (almost). The reason why I mentioned the
    > MFC exception is because the code in the question took MFC base
    > exception to handle Windows structured exceptions (even though the did
    > not have to do it):
    >
    > class CSeException : public CException
    > {
    > ...
    >
    > and then the followed the regular MFC practice of throwing the pointers.
    > The resulting code and suggested framework seem reasonably save to me as
    > long as the users will use MFC conventions consistently (which they will
    > have trouble not to do anyway as the solution introduces dependencies on
    > MFC).


    Following MFC (cleanup) conventions consistently is difficult because
    they are conventions that must be implemented manually, as opposed to
    the automatic cleanup functionality of standard C++ exceptions.


    > ...
    >> Of course, this mess is on its own a good reason not to use MFC... ;-)

    > Agree, I never liked MFC myself. Even now I use C API on Windows --
    > "When in Rome .." -- and AFAIK "Romans" do not use MFC for their killer
    > apps -- or maybe they do now but before they did not.


    AFAIK the Romans use WTL.


    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 26, 2008
    #12
  13. George2

    Pavel Guest

    Alf P. Steinbach wrote:
    > It can easily lead to memory leaks, yes, and it can also easily lead to
    > double destruction. Both are generally disasters. Although possibly
    > not immediate disasters in the sense of an immediate program crash.

    Please.. we are talking about a concrete facility as per the original
    question. They throw pointers and delete them in handlers. Apparently
    they cannot do it in (...) handler (which would create a memory leak but
    I refuse to see how it, per se, can lead to a double destruction) but
    they do not try to do it and they do not have to do it. The MFC style:
    throw CException or its derived classes reasonably handles the issue.
    What disasters are we hinting at here?

    > First, since the code is using MFC exceptions it's not only SEH
    > exceptions that are handled that way.

    Maybe yes, maybe not, we don't have a way to say for sure but is it
    relevant to the subject?

    >
    > Second, the conclusion "and will not create a memory leak" does not follow.

    Ok "does not have to create memory leak" is what I meant to say. Of
    course it does not follow because we do not have the whole code to see
    (and it is the only way to say for sure for any source code and very
    expensive way at that). My only point is that they have enough control
    with this approach to avoid memory leaks. With (...) handlers they would
    not have such facility -- that is all I say.


    > On the contrary, since SEH exceptions can be asynchronous and can occur
    > at any point (e.g. for dereferencing a nullpointer), translating them to
    > C++ throwing of pointer to dynamically allocated exception object is
    > very likely to result in a memory leak, unless all the code is under
    > your control -- and even then...
    >
    >
    >> I am just trying to keep in mind the original problem: processing
    >> Windows sructured exceptions in C++ code.

    >
    > Not a big deal, except it's necessarily C++ implementation-specific, in
    > particular possibly requiring special compiler switches.

    Agreed that the question about the compiler switches was implementation
    specific but we quickly switched to an issue of safe handling of the
    resulting C++ exceptions which is IMHO C++ implementation-independent.

    >> Well, it is documented in the enough details to catch them in C.

    >
    > No, the SEH documentation is for Microsoft's C and C++ language extensions.

    You can handle these exceptions in standard C way by registering a
    callback in _set_se_translator function and translating into regular C++
    exceptions in it. Not sure where a language extension comes into play here.

    >> "No specific language" is correct for the exception client but not for
    >> the code that raises exception (it is C API, after all).

    >
    > No, it's not a C API.

    I mean "the code that raises an exception is C code and it does so by
    using C function RaiseException()". Isn't it C API?

    > The documented language extensions are for C and C++. However, it's not
    > documented how they work together with the (operating system) API, i.e.
    > how these extensions are implemented or what you'd do without them. At
    > least, it didn't use to be documented, and I haven't checked lately.
    >
    > However, that's largely off-topic in clc++.

    Is it ok to discuss the advantages/drawbacks of different approaches of
    adapting non-C++ into C++ here?
    ....

    >>> Of course, this mess is on its own a good reason not to use MFC... ;-)

    >> Agree, I never liked MFC myself. Even now I use C API on Windows --
    >> "When in Rome .." -- and AFAIK "Romans" do not use MFC for their
    >> killer apps -- or maybe they do now but before they did not.

    >
    > AFAIK the Romans use WTL.

    Thanks for the hint -- I will definitely look into WTL. But I meant
    "Windows " for Rome and "Windows developers in Microsoft" for Romans.
    For example for Windows Explorer or Office -- they always used C API (or
    used to do so), one reason being that the correspondent MFC classes
    simply did not exist by the release time. I remember this was the case
    when Windows 95 was released and List View and Tree View were first used
    in its Explorer and this life cycle (feature->C API documentation for
    the feature->MFC API->Fixing MFC API bugs absent in the feature which
    more or less proves that the feature was not implemented with MFC) was
    followed for at least some years after that.

    Regards,
    -Pavel
    Pavel, Jan 26, 2008
    #13
  14. * Pavel:
    > Alf P. Steinbach wrote:
    >> It can easily lead to memory leaks, yes, and it can also easily lead
    >> to double destruction. Both are generally disasters. Although
    >> possibly not immediate disasters in the sense of an immediate program
    >> crash.

    > Please.. we are talking about a concrete facility as per the original
    > question. They throw pointers and delete them in handlers. Apparently
    > they cannot do it in (...) handler (which would create a memory leak but
    > I refuse to see how it, per se, can lead to a double destruction) but
    > they do not try to do it and they do not have to do it. The MFC style:
    > throw CException or its derived classes reasonably handles the issue.
    > What disasters are we hinting at here?


    I think it's as concrete as can be described with words, no hinting.

    Double destruction example would just be example of destroying twice,
    which is easy to do when using manual destruction instead of RAII,
    especially in code where that destruction has to be redundantly repeated
    (as is the case with MFC exception handler code).

    Memory leak + disaster example code:

    void throwX( char const s[] ) { throw std::runtime_error( s ); }

    struct Base()
    {
    virtual ~Base() {}
    virtual void foo() = 0;
    void bar()
    {
    try { foo(); } catch( ... ) { throwX( "Base::bar()" ); }
    }
    };

    struct SillyDerived: Base
    {
    void foo() { int* p = 0; *p = 666; }
    };

    Now with general SEH -> C++ exception translation enabled, and that SEH
    nullpointer exception translated to a C++ throw of pointer to
    dynamically allocated object, a call to bar() leaks memory, and much
    worse, in the general case where a nullpointer exception indicates
    something gone horribly awry, is likely to leave the program in an
    unstable state (memory corruption, invalid assumptions) => disaster.


    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 27, 2008
    #14
  15. George2

    Pavel Guest

    Alf P. Steinbach wrote:
    > I think it's as concrete as can be described with words, no hinting.
    >
    > Double destruction example would just be example of destroying twice,
    > which is easy to do when using manual destruction instead of RAII,
    > especially in code where that destruction has to be redundantly repeated
    > (as is the case with MFC exception handler code).
    >
    > Memory leak + disaster example code:
    >
    > void throwX( char const s[] ) { throw std::runtime_error( s ); }
    >
    > struct Base()
    > {
    > virtual ~Base() {}
    > virtual void foo() = 0;
    > void bar()
    > {
    > try { foo(); } catch( ... ) { throwX( "Base::bar()" ); }
    > }
    > };
    >
    > struct SillyDerived: Base
    > {
    > void foo() { int* p = 0; *p = 666; }
    > };
    >
    > Now with general SEH -> C++ exception translation enabled, and that SEH
    > nullpointer exception translated to a C++ throw of pointer to
    > dynamically allocated object, a call to bar() leaks memory, and much
    > worse, in the general case where a nullpointer exception indicates
    > something gone horribly awry, is likely to leave the program in an
    > unstable state (memory corruption, invalid assumptions) => disaster.

    I agree this example won't work.. but why would anybody use catch(...)
    for structured exception if the point is to catch CseException or
    CException?

    See, my understanding of the idea of the article is this:

    1. Someone has a WIN32 C library that can throw SHE (or, also, WIN32
    itself can do it) and wants to expose these facilities from his C++
    library. Say, that C WIN32 C library has a function

    void cf(); /* can "throw" SHE */

    2. That someone writes a C++ library, including the function, say:

    void cppf() throw(CseException *); // I know MSVC++ does not really
    // support throw(), not in 2005, anyway, but let's pretend it does..
    // maybe it does 2008 or will later.
    // And anyway, the interface is useful just
    // to show that the function can throw CseException

    The library's initialization code will set up the function translating
    SHE to C++ exception

    3. Then, any sensible programmer who uses the C++ library would write
    the client code along these lines:

    try {
    ....
    cppf(); // maybe indirectly
    ....
    } catch(CseException *exPtr) {
    ... // process exception
    // Any person familiar with MFC "style" of exception
    // pointers ownership,
    // will manage the exPtr life style accordingly
    }

    It is certainly more error prone than RAII would be; on the other hand,
    RAII is a very useful but not the only useful way of resource
    management.. otherwise why would we need shared_ptr(), garbage
    collectors and similar machinery. For example, if one wants to post the
    *exPtr or the pointer to _EXCEPTION_POINTERS that it contains onto to a
    queue from where a separate task would process all the exceptions
    asynchronously, RAII will not help.

    BTW, some Microsoft's apparently strange habits in using C++ become
    easier to come to terms with if one keeps in mind their strong
    background in "asynchronous message-driven" programming paradigm. When
    this paradigm is used, the message sometimes originates in one "piece"
    of the program (whether the piece it is a thread, a process or a module)
    and is to be processed and destroyed in another. It is not always
    possible to use RAII in such code.

    Regards
    -Pavel

    >
    >
    > Cheers, & hth.,
    >
    > - Alf
    >
    Pavel, Jan 29, 2008
    #15
  16. * Pavel:
    > Alf P. Steinbach wrote:
    >> I think it's as concrete as can be described with words, no hinting.
    >>
    >> Double destruction example would just be example of destroying twice,
    >> which is easy to do when using manual destruction instead of RAII,
    >> especially in code where that destruction has to be redundantly
    >> repeated (as is the case with MFC exception handler code).
    >>
    >> Memory leak + disaster example code:
    >>
    >> void throwX( char const s[] ) { throw std::runtime_error( s ); }
    >>
    >> struct Base()
    >> {
    >> virtual ~Base() {}
    >> virtual void foo() = 0;
    >> void bar()
    >> {
    >> try { foo(); } catch( ... ) { throwX( "Base::bar()" ); }
    >> }
    >> };
    >>
    >> struct SillyDerived: Base
    >> {
    >> void foo() { int* p = 0; *p = 666; }
    >> };
    >>
    >> Now with general SEH -> C++ exception translation enabled, and that
    >> SEH nullpointer exception translated to a C++ throw of pointer to
    >> dynamically allocated object, a call to bar() leaks memory, and much
    >> worse, in the general case where a nullpointer exception indicates
    >> something gone horribly awry, is likely to leave the program in an
    >> unstable state (memory corruption, invalid assumptions) => disaster.

    >
    > I agree this example won't work.. but why would anybody use catch(...)
    > for structured exception if the point is to catch CseException or
    > CException?


    Especially with virtual functions, but also with function pointers and
    templated functionality, at the point where you write the catch(...) you
    don't know what code is executed, what exceptions can occur, and you
    don't write catch(...) in order to use a language extensions that makes
    this catch SEH exceptions, but in order to catch any /C++/ exception.

    And in particular, that catch(...) can reside in existing years old code
    that calls your new code.

    E.g. Base above might be a SuperDuper library class from Microsoft
    (quickly searching through the MS code on my machine, however, I found
    only 1 instance of this pattern), and SillyDerived your new shiny class,
    throwing SEH exception by accident.

    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 29, 2008
    #16
    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. Replies:
    14
    Views:
    585
    alisonken1
    Apr 21, 2006
  2. George2

    Structured exception

    George2, Jan 19, 2008, in forum: C++
    Replies:
    1
    Views:
    279
    Rolf Magnus
    Jan 19, 2008
  3. George2
    Replies:
    4
    Views:
    392
    Mike Smith
    Jan 28, 2008
  4. Peter
    Replies:
    34
    Views:
    1,913
    James Kanze
    Oct 17, 2009
  5. single threaded

    Best way to display and administer semi-structured data.

    single threaded, Jun 11, 2005, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    108
    single threaded
    Jun 17, 2005
Loading...

Share This Page