* [Caml-list] C++ Throws @ 2004-08-27 22:31 David McClain 2004-08-27 23:24 ` Brian Hurt 0 siblings, 1 reply; 12+ messages in thread From: David McClain @ 2004-08-27 22:31 UTC (permalink / raw) To: caml-list I now see that OCaml is not converting anything, per se... Apparently when the throw handler detects an unhandled condition it decides to call abort(), against which there is no defense. However, it also appears that once a C call returns to OCaml, OCaml reinstates its own trap handling, overriding anything that may have been left in place by the called C function. This is possibly understandable. But by the same token, at startup, I call a C main() which in turn starts up OCaml. That give it a chance to establish its environment. Then the main routine designated in OCaml calls another C routine that encloses a callback to OCaml within try-catch, and this is being overridden by OCaml. So there appears to be something relatively complex going on across the foreign function interface with OCaml and C. This override is what frustrates the attempts to create a generic C++ exception handler. David McClain Senior Corporate Scientist Avisere, Inc. david.mcclain@avisere.com +1.520.390.7738 (USA) ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-27 22:31 [Caml-list] C++ Throws David McClain @ 2004-08-27 23:24 ` Brian Hurt 2004-08-28 0:11 ` David McClain 2004-08-28 0:22 ` David McClain 0 siblings, 2 replies; 12+ messages in thread From: Brian Hurt @ 2004-08-27 23:24 UTC (permalink / raw) To: David McClain; +Cc: caml-list On Fri, 27 Aug 2004, David McClain wrote: > I now see that OCaml is not converting anything, per se... Apparently > when the throw handler detects an unhandled condition it decides to > call abort(), against which there is no defense. I don't know what precisely is going on here, but Ocaml interfaces to C, which doesn't know anything about exceptions. You might try something like (sorry, I'm no C++ guru): extern "C" value foo(value c); value foo(value C) { /* normal Ocaml wrapper code for C */ try { /* exception throwing code for C++. */ } with (Exception e) { /* Translate the C++ exception to an Ocaml exception */ } } The big difference between a C++ function and C function is the name mangling. I doubt Ocaml could find a C++ function for linking after it was name mangled. So the extern "C" tells C++ to not namemangle the function name. There is no way I know of to determine what exceptions a function call might throw. > So there appears to be something relatively complex going on across the > foreign function interface with OCaml and C. This override is what > frustrates the attempts to create a generic C++ exception handler. I think you also have a C/C++ interface problem (and yes, Virginia, they do exist). -- "Usenet is like a herd of performing elephants with diarrhea -- massive, difficult to redirect, awe-inspiring, entertaining, and a source of mind-boggling amounts of excrement when you least expect it." - Gene Spafford Brian ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-27 23:24 ` Brian Hurt @ 2004-08-28 0:11 ` David McClain 2004-08-28 1:40 ` skaller 2004-08-28 0:22 ` David McClain 1 sibling, 1 reply; 12+ messages in thread From: David McClain @ 2004-08-28 0:11 UTC (permalink / raw) To: Brian Hurt; +Cc: caml-list Hi Brian, Yes, that technique is the one that I said previously works just fine. I was hoping for a higher level generic handler, instead of wrapping each individual lib call with this try-catch block. I have been doing C++ to OCaml for years now with no difficulty. The catch here is that OCaml appears to be interposing between the established higher level catch handlers and the source of the throw exceptions. It appears to insist on not allowing any lower dynamic exceptions to propagate above its interface with a C call. David McClain Senior Corporate Scientist Avisere, Inc. +1.520.390.7738 (USA) david.mcclain@avisere.com ----- Original Message ----- From: "Brian Hurt" <bhurt@spnz.org> To: "David McClain" <David.McClain@Avisere.com> Cc: <caml-list@inria.fr> Sent: Friday, August 27, 2004 16:24 Subject: Re: [Caml-list] C++ Throws > On Fri, 27 Aug 2004, David McClain wrote: > > > I now see that OCaml is not converting anything, per se... Apparently > > when the throw handler detects an unhandled condition it decides to > > call abort(), against which there is no defense. > > I don't know what precisely is going on here, but Ocaml interfaces to C, > which doesn't know anything about exceptions. You might try something > like (sorry, I'm no C++ guru): > > extern "C" value foo(value c); > > value foo(value C) { > /* normal Ocaml wrapper code for C */ > try { > /* exception throwing code for C++. */ > } > with (Exception e) { > /* Translate the C++ exception to an Ocaml exception */ > } > } > > The big difference between a C++ function and C function is the name > mangling. I doubt Ocaml could find a C++ function for linking after it > was name mangled. So the extern "C" tells C++ to not namemangle the > function name. > > There is no way I know of to determine what exceptions a function call > might throw. > > > So there appears to be something relatively complex going on across the > > foreign function interface with OCaml and C. This override is what > > frustrates the attempts to create a generic C++ exception handler. > > I think you also have a C/C++ interface problem (and yes, Virginia, they > do exist). > > -- > "Usenet is like a herd of performing elephants with diarrhea -- massive, > difficult to redirect, awe-inspiring, entertaining, and a source of > mind-boggling amounts of excrement when you least expect it." > - Gene Spafford > Brian > > ------------------- > To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr > Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 0:11 ` David McClain @ 2004-08-28 1:40 ` skaller 2004-08-28 4:13 ` David McClain 0 siblings, 1 reply; 12+ messages in thread From: skaller @ 2004-08-28 1:40 UTC (permalink / raw) To: David McClain; +Cc: Brian Hurt, caml-list On Sat, 2004-08-28 at 10:11, David McClain wrote: > Hi Brian, > > Yes, that technique is the one that I said previously works just fine. I was > hoping for a higher level generic handler, instead of wrapping each > individual lib call with this try-catch block. > > I have been doing C++ to OCaml for years now with no difficulty. The catch > here is that OCaml appears to be interposing between the established higher > level catch handlers and the source of the throw exceptions. It appears to > insist on not allowing any lower dynamic exceptions to propagate above its > interface with a C call. No, I doubt that. What's actually happening is quite the opposite. C++ stack unwinding involves synchonously destroying stack objects and NOT returning control until the handler is reached. But you've stuck some Ocaml stack frames in the way. Far from Ocaml 'grabbing control', it isn't doing anything. Ocaml isn't ever getting control -- C++ knows nothing and just keeps going -- it doesn't execute the 'return' instruction for the callers program counter, it throws it away. Actually it's more complex than that -- EH has two jobs: (a) locate the handler (b) unwind the stack up to it then give it control It is allowed to unwind the stack whilst looking for the handler. It is also allowed to locate the handler FIRST, and THEN unwind. In particular if there is NO handler, it is allowed to core dump on the spot without unwinding anything -- the reason being that you then get a dump which actually includes debugging information :) Either way it is C++ which will either abort() because it can't find a handler, or corrupt your system and lock up or crash, if it it actually get stuck misinterpreting the Ocaml stack frames either during unwinding or trying to find the stack frames .. don't even count on abort() being called. I think it is possible to write generic handler, but only if you have detailed implemention details from you compiler vendor on how EH is implemented on your platform :( -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 1:40 ` skaller @ 2004-08-28 4:13 ` David McClain 2004-08-28 4:55 ` David Brown ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: David McClain @ 2004-08-28 4:13 UTC (permalink / raw) To: skaller; +Cc: Brian Hurt, caml-list Okay Skaller... (John, isn't it?) Smarty pants... you may be very correct about most of this, but I can show you that an unhandled throw is being turned into a call to abort() from which there is no recovery. I do find it amazing that C++ would be dumb enough to try to scaffold raw stack frames, instead of using some kind of dynamic link pointers to reach each frame C++. How in the world would any kind of cross-language interoperability ever function if this were the case. Mind you I'm not disputing your estimate here, it's just that I find it a bit incredulous. But whatever, at least with pseudo-functional closures I can handle this problem the way that seems most natural, and down at the module level where it probably belongs, even if it is more expensive in code and runtime. What matters is programmer productivity and being able to prevent the application from aborting just because of an indexing error. This is an interactive application and abrupt aborts aren't very pleasant for the user, nor are they necessary. - DM ----- Original Message ----- From: "skaller" <skaller@users.sourceforge.net> To: "David McClain" <dmcclain1@mindspring.com> Cc: "Brian Hurt" <bhurt@spnz.org>; "caml-list" <caml-list@inria.fr> Sent: Friday, August 27, 2004 18:40 Subject: Re: [Caml-list] C++ Throws > On Sat, 2004-08-28 at 10:11, David McClain wrote: > > Hi Brian, > > > > Yes, that technique is the one that I said previously works just fine. I was > > hoping for a higher level generic handler, instead of wrapping each > > individual lib call with this try-catch block. > > > > I have been doing C++ to OCaml for years now with no difficulty. The catch > > here is that OCaml appears to be interposing between the established higher > > level catch handlers and the source of the throw exceptions. It appears to > > insist on not allowing any lower dynamic exceptions to propagate above its > > interface with a C call. > > No, I doubt that. What's actually happening is quite the opposite. > C++ stack unwinding involves synchonously destroying stack > objects and NOT returning control until the handler is reached. > > But you've stuck some Ocaml stack frames in the way. > Far from Ocaml 'grabbing control', it isn't doing anything. > Ocaml isn't ever getting control -- C++ knows nothing > and just keeps going -- it doesn't execute the > 'return' instruction for the callers program counter, > it throws it away. > > Actually it's more complex than that -- EH has two jobs: > (a) locate the handler > (b) unwind the stack up to it then give it control > > It is allowed to unwind the stack whilst looking > for the handler. > > It is also allowed to locate the handler FIRST, > and THEN unwind. In particular if there is NO handler, > it is allowed to core dump on the spot without unwinding > anything -- the reason being that you then get a dump > which actually includes debugging information :) > > Either way it is C++ which will either abort() > because it can't find a handler, or corrupt > your system and lock up or crash, if it it actually > get stuck misinterpreting the Ocaml stack frames > either during unwinding or trying to find > the stack frames .. don't even count on abort() > being called. > > I think it is possible to write generic handler, > but only if you have detailed implemention details > from you compiler vendor on how EH is implemented > on your platform :( > > > -- > John Skaller, mailto:skaller@users.sf.net > voice: 061-2-9660-0850, > snail: PO BOX 401 Glebe NSW 2037 Australia > Checkout the Felix programming language http://felix.sf.net > > > > ------------------- > To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr > Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 4:13 ` David McClain @ 2004-08-28 4:55 ` David Brown 2004-08-28 7:44 ` Ville-Pertti Keinonen 2004-08-28 7:48 ` Radu-Mihail Obada 2004-08-28 8:17 ` Xavier Leroy 2004-08-28 9:31 ` skaller 2 siblings, 2 replies; 12+ messages in thread From: David Brown @ 2004-08-28 4:55 UTC (permalink / raw) To: David McClain; +Cc: skaller, Brian Hurt, caml-list On Fri, Aug 27, 2004 at 09:13:52PM -0700, David McClain wrote: > I do find it amazing that C++ would be dumb enough to try to scaffold raw > stack frames, instead of using some kind of dynamic link pointers to reach > each frame C++. How in the world would any kind of cross-language > interoperability ever function if this were the case. Mind you I'm not > disputing your estimate here, it's just that I find it a bit incredulous. It might depend on the compiler and possibly options. Handling exceptions by manually unwinding stack frames is popular because it transfers the cost of exceptions to their occurrences, rather than each handle clause. This is a big efficiency gain for code where exceptions do not occur most of the time. I didn't catch which compiler you are using, but recent versions of G++ _do_ use unwinding exception handling that would be thrown off by the ocaml stack frames. Dave ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 4:55 ` David Brown @ 2004-08-28 7:44 ` Ville-Pertti Keinonen 2004-08-28 7:48 ` Radu-Mihail Obada 1 sibling, 0 replies; 12+ messages in thread From: Ville-Pertti Keinonen @ 2004-08-28 7:44 UTC (permalink / raw) To: David Brown, David McClain; +Cc: caml-list David Brown wrote: >On Fri, Aug 27, 2004 at 09:13:52PM -0700, David McClain wrote: > > > >>I do find it amazing that C++ would be dumb enough to try to scaffold raw >>stack frames, instead of using some kind of dynamic link pointers to reach >>each frame C++. How in the world would any kind of cross-language >>interoperability ever function if this were the case. Mind you I'm not >> >> ... >I didn't catch which compiler you are using, but recent versions of G++ >_do_ use unwinding exception handling that would be thrown off by the ocaml >stack frames. > > He was using Apple's version of GCC on MacOS X, which definitely uses stack unwinding for handling exceptions. In general, it's unreasonable to expect exceptions to work across language boundaries just because straightforward call interfaces do if there isn't a specifically documented way to deal with them. With C++ in particular, since the details of exceptions are implementation-specific, they aren't even compatible across different C++ implementations, much less with other languages (unless specifically designed to be - e.g. presumably .NET C++). Also, Unix signal handlers aren't really related to exceptions. Signals can be asynchronous, while exceptions are thrown from specific points in code. It's possible to translate some signals to exceptions safely (ones that are actually generated by specific instructions in the same thread), which I believe OCaml does, but the signal related stuff in the C interface is related to making asynchronous signal handlers written in OCaml safe to call. ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 4:55 ` David Brown 2004-08-28 7:44 ` Ville-Pertti Keinonen @ 2004-08-28 7:48 ` Radu-Mihail Obada 1 sibling, 0 replies; 12+ messages in thread From: Radu-Mihail Obada @ 2004-08-28 7:48 UTC (permalink / raw) To: caml-list I may be a little (maybe even a little more?) off-topic here, but just to make things clear: C++' exception handling mechanism indeed calls abort() when there is no exception handler that matches the current exception type (C++ type substition rules considered). (Actually, a C++ implementation is required to call terminate() for an uncaught exception, among other things.). Just my 2 cents. ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 4:13 ` David McClain 2004-08-28 4:55 ` David Brown @ 2004-08-28 8:17 ` Xavier Leroy 2004-08-28 9:24 ` skaller 2004-08-28 9:31 ` skaller 2 siblings, 1 reply; 12+ messages in thread From: Xavier Leroy @ 2004-08-28 8:17 UTC (permalink / raw) To: David McClain; +Cc: skaller, Brian Hurt, caml-list > I do find it amazing that C++ would be dumb enough to try to scaffold raw > stack frames, instead of using some kind of dynamic link pointers to reach > each frame. There are indeed two "schools" of exception handling: one that unwind stack frames one by one until an exception handler is found, and one that maintains at run-time a chaining between exception handling blocks on the stack, so that no stack searching is necessary when an exception is thrown. The first school is exemplified by C++, Modula-3, Java and C#; the second school by Lisp, Caml and to some extent Prolog (if you view backtracking as a generalization of exception handling). A good description of the two approaches is the following paper: "A Single Intermediate Language That Supports Multiple Implementations of Exceptions",, Norman Ramsey and Simon Peyton Jones, PLDI 2000. http://research.microsoft.com/Users/simonpj/Papers/c--/c--exn.htm The two approaches have very different performance trade-offs. To make things worse, many people from the first school are not even aware of the second approach. So, as usual, there is no hope to see the world converge on a single exception mechanism. > How in the world would any kind of cross-language > interoperability ever function if this were the case. Cross--language exception interoperability is certainly a challenge. There are C compilers (MSVC, Tru64 cc) that provide C++-style exception handling compatible with C++, but that's not too hard given that the same compilers double as C++ compilers :-) Some ABI (Application Binary Interfaces) specify the format of stack descriptors and the unwinding algorithm, but not all. The only portable way is to install catch-all exception handlers at the boundaries between the two languages whose job is to convert exceptions from one language into exceptions from the other language. The Caml bytecode interpreter does something like this when interoperating with C, using setjmp/longjmp to represent exceptions on the C side. For C++ to Caml callbacks, you can use callback_exn to invoke the Caml code; it reifies whatever Caml exceptions can get out of the Caml code as special return values, which the C++ wrapper can test and then throw the appropriate C++ exception. For the reverse direction (Caml calling C++), I'm afraid the only solution is to use a C++ catch-all clause to turn C++ exceptions into Caml exceptions. Hope this clarifies the issue. - Xavier Leroy ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 8:17 ` Xavier Leroy @ 2004-08-28 9:24 ` skaller 0 siblings, 0 replies; 12+ messages in thread From: skaller @ 2004-08-28 9:24 UTC (permalink / raw) To: Xavier Leroy; +Cc: David McClain, Brian Hurt, caml-list On Sat, 2004-08-28 at 18:17, Xavier Leroy wrote: > There are indeed two "schools" of exception handling: one that unwind > stack frames one by one until an exception handler is found, and one > that maintains at run-time a chaining between exception handling > blocks on the stack, so that no stack searching is necessary when an > exception is thrown. > > The first school is exemplified by C++, Modula-3, Java and C#; the > second school by Lisp, Caml and to some extent Prolog (if you view > backtracking as a generalization of exception handling). C++ is required by the ISO Standard to unwind each frame to the handler, executing destructors in FILO order. Ocaml doesn't need to do that, it has a garbage collector which finalises blocks out of order. > The two approaches have very different performance trade-offs. To > make things worse, many people from the first school are not even > aware of the second approach. So, as usual, there is no hope to see > the world converge on a single exception mechanism. As above -- for C++ it is tied up with the requirement to execute destructors of stacked objects in a FIFO manner. Simply dropping back to the handler isn't an option. So it isn't necessarily ignorance that will prevent convergence -- there are distinct architectural models to consider, in this finalisation in C++ must be FILO in both normal and exceptional exits -- C++ code is allowed to rely on destructors executing in reverse order to constructors. > > How in the world would any kind of cross-language > > interoperability ever function if this were the case. The C++ committee was only ever concerned with C interoperability. Its not their job to consider other languages, especially ones that do not have ISO Standards backing them, where inter-committee liason is impossible. > For the reverse direction (Caml calling C++), I'm afraid the only > solution is to use a C++ catch-all clause to turn C++ exceptions into > Caml exceptions. Which can't be done in a portable manner: since the catch-all cannot have an associated static type, you can't actually refer to the exception object in the handler. Other languages -- Java and now Python -- have a top level exception type from which all exceptions must be derived. In C++, the type doesn't even have to be polymorphic -- you can throw an int or string if you want. Perhaps that's stupid but the reason is compatibility with earlier C++ code which typically threw int or char *. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-28 4:13 ` David McClain 2004-08-28 4:55 ` David Brown 2004-08-28 8:17 ` Xavier Leroy @ 2004-08-28 9:31 ` skaller 2 siblings, 0 replies; 12+ messages in thread From: skaller @ 2004-08-28 9:31 UTC (permalink / raw) To: David McClain; +Cc: Brian Hurt, caml-list On Sat, 2004-08-28 at 14:13, David McClain wrote: > Okay Skaller... (John, isn't it?) Yup > Smarty pants... I would consider over a decade as a National Body member of the ISO C++ Standardisation committee .. .. more a case of Dumb and Dumber .. :) If only I'd had Ocaml at the time I joined up I'd never have bothered trying to convince them to implement things that Ocaml already does: lexically scoped functions, closures, variants, parametric polymorphism .. -- John Skaller, mailto:skaller@users.sf.net voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Caml-list] C++ Throws 2004-08-27 23:24 ` Brian Hurt 2004-08-28 0:11 ` David McClain @ 2004-08-28 0:22 ` David McClain 1 sibling, 0 replies; 12+ messages in thread From: David McClain @ 2004-08-28 0:22 UTC (permalink / raw) To: Brian Hurt; +Cc: caml-list [-- Attachment #1: Type: text/plain, Size: 3433 bytes --] The main reason I was looking for a higher level generic mechanism for catching C++ throws is the desparate lack of functional closures in C++. If there were such a thing, then it would easy to wrap all the lower level calls in a safe try-catch block which has the closure passed to it... Alas, I sat down and invented a poor-man's functional closure system for C++, along the lines of CAMLparam1, etc.... The world is welcome to this... (attached) It is intended for use in OCaml C++ interface stubs, hence the use of value parameters in the closure classes. An example of its use is here: // ----------------------------------------------------------- extern "C" void foreign_array_blit_ml_to_f(value varr1, value voff1, value varr2, value voff2, value vnel) { VClosure5(clos, varr1,voff1,varr2,voff2,vnel, { long off1 = Long_val(VClArg(voff1)); long nel = Long_val(VClArg(vnel)); foreign_array fsrc(FOREIGN_DOUBLE, 1, &nel, (void*)((double*)VClArg(varr1) + off1), foreign_array::STATIC); long off2 = Long_val(VClArg(voff2)); foreign_array *pdst = pdata(VClArg(varr2)); array_blit(&fsrc, 0, pdst, off2, nel); }, &varr1); safe_call(clos); } // ----------------------------------------------------------- - DM ----- Original Message ----- From: "Brian Hurt" <bhurt@spnz.org> To: "David McClain" <David.McClain@Avisere.com> Cc: <caml-list@inria.fr> Sent: Friday, August 27, 2004 16:24 Subject: Re: [Caml-list] C++ Throws > On Fri, 27 Aug 2004, David McClain wrote: > > > I now see that OCaml is not converting anything, per se... Apparently > > when the throw handler detects an unhandled condition it decides to > > call abort(), against which there is no defense. > > I don't know what precisely is going on here, but Ocaml interfaces to C, > which doesn't know anything about exceptions. You might try something > like (sorry, I'm no C++ guru): > > extern "C" value foo(value c); > > value foo(value C) { > /* normal Ocaml wrapper code for C */ > try { > /* exception throwing code for C++. */ > } > with (Exception e) { > /* Translate the C++ exception to an Ocaml exception */ > } > } > > The big difference between a C++ function and C function is the name > mangling. I doubt Ocaml could find a C++ function for linking after it > was name mangled. So the extern "C" tells C++ to not namemangle the > function name. > > There is no way I know of to determine what exceptions a function call > might throw. > > > So there appears to be something relatively complex going on across the > > foreign function interface with OCaml and C. This override is what > > frustrates the attempts to create a generic C++ exception handler. > > I think you also have a C/C++ interface problem (and yes, Virginia, they > do exist). > > -- > "Usenet is like a herd of performing elephants with diarrhea -- massive, > difficult to redirect, awe-inspiring, entertaining, and a source of > mind-boggling amounts of excrement when you least expect it." > - Gene Spafford > Brian > > ------------------- > To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr > Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > [-- Attachment #2: TClosure.h --] [-- Type: application/octet-stream, Size: 2598 bytes --] // TClosure.h -- Simulation of Functional Closures in C++ // DM/MCFA 08/04 // #ifndef __TCLOSURE_H__ #define __TCLOSURE_H__ extern "C" { #include <caml/mlvalues.h> #include <caml/memory.h> #include <caml/alloc.h> #include <caml/fail.h> #include <caml/custom.h> #include <caml/intext.h> }; class TClosure { public: TClosure() {}; virtual ~TClosure() {}; virtual void operator()() = 0; }; #ifdef __TClosure_Instantiate__ void safe_call(TClosure &closure) { try { closure(); } catch(const char* msg) { failwith((char*)msg); } } #else extern void safe_call(TClosure &closure); #endif // ------------------------------------------------ // Internal macros // #define __VClosureHead() \ struct closure: public TClosure \ { \ value *m_pparm; \ value m_result; \ closure(value *pparm) \ :m_pparm(pparm) \ {} \ #define __VClosureArgs1(arg) \ enum {arg}; #define __VClosureArgs2(arg1,arg2) \ enum {arg1,arg2}; #define __VClosureArgs3(arg1,arg2,arg3) \ enum {arg1,arg2,arg3}; #define __VClosureArgs4(arg1,arg2,arg3,arg4) \ enum {arg1,arg2,arg3,arg4}; #define __VClosureArgs5(arg1,arg2,arg3,arg4,arg5) \ enum {arg1,arg2,arg3,arg4,arg5}; #define __VClosureTail(name,body,env) \ void operator()() \ { body } \ } name(env); // ------------------------------------------------------ // API Level Macros #define VClosure(name,body,env) \ __VClosureHead() \ __VClosureTail(name,body,env) #define VClosure1(name,arg,body,env) \ __VClosureHead() \ __VClosureArgs1(arg) \ __VClosureTail(name,body,env) #define VClosure2(name,arg1,arg2,body,env) \ __VClosureHead() \ __VClosureArgs2(arg1,arg2) \ __VClosureTail(name,body,env) #define VClosure3(name,arg1,arg2,arg3,body,env) \ __VClosureHead() \ __VClosureArgs3(arg1,arg2,arg3) \ __VClosureTail(name,body,env) #define VClosure4(name,arg1,arg2,arg3,arg4,body,env) \ __VClosureHead() \ __VClosureArgs4(arg1,arg2,arg3,arg4) \ __VClosureTail(name,body,env) #define VClosure5(name,arg1,arg2,arg3,arg4,arg5,body,env) \ __VClosureHead() \ __VClosureArgs5(arg1,arg2,arg3,arg4,arg5) \ __VClosureTail(name,body,env) #define VClArg(name) m_pparm[name] #define VClReturn(val) m_result = val; #define VClResult(closure_name) closure_name.m_result #endif // __TCLOSURE_H__ // -- end of TClosure.h -- // ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2004-08-28 9:32 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-08-27 22:31 [Caml-list] C++ Throws David McClain 2004-08-27 23:24 ` Brian Hurt 2004-08-28 0:11 ` David McClain 2004-08-28 1:40 ` skaller 2004-08-28 4:13 ` David McClain 2004-08-28 4:55 ` David Brown 2004-08-28 7:44 ` Ville-Pertti Keinonen 2004-08-28 7:48 ` Radu-Mihail Obada 2004-08-28 8:17 ` Xavier Leroy 2004-08-28 9:24 ` skaller 2004-08-28 9:31 ` skaller 2004-08-28 0:22 ` David McClain
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox