caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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-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

* 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

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;
as well as URLs for NNTP newsgroup(s).