|
#1
|
|
|
|
|
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 |
|
|
|
#2
|
|
|
|
|
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, > > [..] > 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-lit....html#faq-17.7 is missing that the best way is to catch const reference |
|
#3
|
|
|
|
|
George2 wrote:
[..] > > 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 |
|
#4
|
|
|
|
|
anon wrote:
> George2 wrote: > > 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? |
|
#5
|
|
|
|
|
* Pavel:
> anon wrote: > > 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 |
|
#6
|
|
|
|
|
Pavel wrote:
> anon wrote: > > 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-lit...html#faq-16.15 Do you have an example where "delete this" would be good? Or at least not bad? |
|
#7
|
|
|
|
|
Pavel wrote:
> George2 wrote: ... >> >> 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/lib...h5(VS.71).aspx -Pavel |
|
#8
|
|
|
|
|
Alf P. Steinbach wrote:
> * Pavel: > > 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 |
|
#9
|
|
|
|
|
* Pavel:
> Alf P. Steinbach wrote: > 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> |
|
#10
|
|
|
|
|
anon wrote:
> Pavel wrote: >> anon wrote: >>> George2 wrote: >>>> Hello everyone, >>>> .... > > [..] 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 |
|
#11
|
|
|
|
|
....
>>>>> 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 |
|
#12
|
|
|
|
|
* Pavel:
> ... > ... > 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 > 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++. [..] > > 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 |
|
#13
|
|
|
|
|
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 |
|
#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 |
|
#15
|
|
|
|
|
Alf P. Steinbach wrote:
[..] > { > 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 [..] |
|
|
|
|
| Similar Threads | |
| Handle C++ exception and structured exception together Hello everyone, I am learning set_se_translator, and there are some good resources about how to translate structured exception into C++ exception, like, [..] 1. |
|
| Handle C++ exception and structured exception together Hello everyone, I am learning set_se_translator, and there are some good resources about how to translate structured exception into C++ exception, like, [..] 1. What... |
|
| Structured exception Hello everyone, I am learning structured exception from, [..] I read a couple of links from MSDN, but still confused what is structured exception, what is the differences... |
|
| Structured exception Hello everyone, I am learning structured exception from, [..] I read a couple of links from MSDN, but still confused what is structured exception, what is the differences... |
|
| Getting the exception code from a structured exception in a catch (...) block In my program I'm throwing C++ exceptions all around and need to catch structured exceptions and re-throw them as C++ exceptions. I've managed to do it, but it's a bit... |
|
|
All times are GMT. The time now is 08:57 AM. | Privacy Policy
|