propagation of exceptions over module/language boundaries

Discussion in 'C++' started by ben mitch, Jun 13, 2008.

  1. ben mitch

    ben mitch Guest

    Hi

    I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    immediately that the question *may* turn out to be
    compiler-/os-specific, in which case I apologize. But I wonder if
    there's an underlying truth.

    We are writing a (cross-platform) 'framework' application (in C++, as it
    happens) that allows users to author 'plugins' (as shared library
    modules). Since the lifetime of plugins is expected to be long, and the
    framework may be updated using a later compiler version, we have chosen
    to offer a C interface to those plugins to avoid issues with changing
    ABIs (as far as I understand it). Plugins are expected to export a
    single undecorated function, Event(EventData* data), and may call back
    to the framework through a number of undecorated functions exported from
    an API module, 'api', also authored in C++. Commonly, then, the
    framework will load a plugin, call its Event() function, and that
    function will call one of these callback functions on the API.

    At this point I have to own up and say I don't fully understand linking
    or calling conventions, so when I say we "offer a C interface" what I
    mean is that api is compiled to export its functions undecorated (sort
    of with the use of extern "C", though actually there's some other stuff
    going on that I'd rather not get into so I'm hoping that's a
    sufficiently good approximation - api is a C++ module but its exports
    are undecorated). Also, plugins export their Event() function as extern "C".

    Motivation: It would be convenient if the api could throw an exception
    that the framework would recognise. It would pass painlessly up through
    any user code without the user having to do anything, and the framework
    could find out what happened and generate a useful error report. The
    alternative is that we enforce that all API functions do not throw and
    instead return error codes - the onus is then on the plugin author to
    catch the error and return it to the framework (or, if they are
    authoring in C++, they could throw an exception themselves, but i'm not
    sure if that's not the same question again).

    Now, 'api' is authored in C++, and so is the framework, but user plugins
    may be authored in C or C++ (or, in fact, any other language that can
    meet the requirements of the interface). So my initial thinking was that
    we couldn't use exceptions, much as they're great imho. However, in my
    current dev copy, i'm finding exceptions work fine. My worry is that in
    my current dev copy i'm compiling the framework, the api, *and* the test
    plugin, all with the same compiler (cl v14, win xp), which may be hiding
    problems that would arise once we go more mix and match. In addition,
    I'm writing this particular plugin in C++, so everything is C++ save the
    actual exported function declarations.

    So... the question is, should we avoid throwing exceptions across these
    module boundaries, or is it ok to do so? I could actually test this to
    some extent by installing some other compilers, but I'm thinking that
    that's not going to be a thorough test anyway, so I'd rather reach some
    understanding. For instance...

    * framework loads "plugin"
    * framework calls plugin::Event()
    * plugin calls api::Sum()
    * error condition occurs in Sum()
    * Sum() throws exception of type X

    or, to put that another way, the call stack looks like:

    framework::main() (C++)
    --> plugin::Event() (C)
    --> api::Sum() (C++)
    throw X;

    Now, if X is, say, an int, will it pass safely back up through "plugin"
    in all cases, even if plugin is compiled with an (old, perhaps) C
    compiler that is strictly not aware of exceptions? Is this a
    compiler-/os-specific question? what if X is a C struct defined in api.h?

    From what I have learned about exceptions and how they are implemented,
    I don't immediately see a problem with passing one 'through'
    exception-unaware code in this way. There will be no handlers on the
    stack associated with the C-code, but I'm supposing that this means that
    control will just pass (effectively) directly from the "throw" statement
    in api to the "catch" block in framework. But I'm worried that the way
    the stack is arranged to accomodate the two cross-module-boundary calls
    will somehow interfere with this mechanism. I am also worried that the
    type of the object will not be recognised when it reaches framework - I
    am fine with sticking with const char* as an exception type if that's
    the only reliable option, but a struct with a code, a message, and some
    source information would be preferable, of course.

    Phew. I hope that's clear.

    Thanks in advance for any comments.
    Ben Mitch
    ben mitch, Jun 13, 2008
    #1
    1. Advertising

  2. ben mitch

    jacob navia Guest

    ben mitch wrote:
    > Hi
    >
    > I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    > immediately that the question *may* turn out to be
    > compiler-/os-specific, in which case I apologize. But I wonder if
    > there's an underlying truth.
    >
    > We are writing a (cross-platform) 'framework' application (in C++, as it
    > happens) that allows users to author 'plugins' (as shared library
    > modules). Since the lifetime of plugins is expected to be long, and the
    > framework may be updated using a later compiler version, we have chosen
    > to offer a C interface to those plugins to avoid issues with changing
    > ABIs (as far as I understand it). Plugins are expected to export a
    > single undecorated function, Event(EventData* data), and may call back
    > to the framework through a number of undecorated functions exported from
    > an API module, 'api', also authored in C++. Commonly, then, the
    > framework will load a plugin, call its Event() function, and that
    > function will call one of these callback functions on the API.
    >
    > At this point I have to own up and say I don't fully understand linking
    > or calling conventions, so when I say we "offer a C interface" what I
    > mean is that api is compiled to export its functions undecorated (sort
    > of with the use of extern "C", though actually there's some other stuff
    > going on that I'd rather not get into so I'm hoping that's a
    > sufficiently good approximation - api is a C++ module but its exports
    > are undecorated). Also, plugins export their Event() function as extern
    > "C".
    >
    > Motivation: It would be convenient if the api could throw an exception
    > that the framework would recognise. It would pass painlessly up through
    > any user code without the user having to do anything, and the framework
    > could find out what happened and generate a useful error report. The
    > alternative is that we enforce that all API functions do not throw and
    > instead return error codes - the onus is then on the plugin author to
    > catch the error and return it to the framework (or, if they are
    > authoring in C++, they could throw an exception themselves, but i'm not
    > sure if that's not the same question again).
    >
    > Now, 'api' is authored in C++, and so is the framework, but user plugins
    > may be authored in C or C++ (or, in fact, any other language that can
    > meet the requirements of the interface). So my initial thinking was that
    > we couldn't use exceptions, much as they're great imho. However, in my
    > current dev copy, i'm finding exceptions work fine. My worry is that in
    > my current dev copy i'm compiling the framework, the api, *and* the test
    > plugin, all with the same compiler (cl v14, win xp), which may be hiding
    > problems that would arise once we go more mix and match. In addition,
    > I'm writing this particular plugin in C++, so everything is C++ save the
    > actual exported function declarations.
    >
    > So... the question is, should we avoid throwing exceptions across these
    > module boundaries, or is it ok to do so? I could actually test this to
    > some extent by installing some other compilers, but I'm thinking that
    > that's not going to be a thorough test anyway, so I'd rather reach some
    > understanding. For instance...
    >
    > * framework loads "plugin"
    > * framework calls plugin::Event()
    > * plugin calls api::Sum()
    > * error condition occurs in Sum()
    > * Sum() throws exception of type X
    >
    > or, to put that another way, the call stack looks like:
    >
    > framework::main() (C++)
    > --> plugin::Event() (C)
    > --> api::Sum() (C++)
    > throw X;
    >
    > Now, if X is, say, an int, will it pass safely back up through "plugin"
    > in all cases, even if plugin is compiled with an (old, perhaps) C
    > compiler that is strictly not aware of exceptions? Is this a
    > compiler-/os-specific question? what if X is a C struct defined in api.h?
    >
    > From what I have learned about exceptions and how they are implemented,
    > I don't immediately see a problem with passing one 'through'
    > exception-unaware code in this way. There will be no handlers on the
    > stack associated with the C-code, but I'm supposing that this means that
    > control will just pass (effectively) directly from the "throw" statement
    > in api to the "catch" block in framework. But I'm worried that the way
    > the stack is arranged to accomodate the two cross-module-boundary calls
    > will somehow interfere with this mechanism. I am also worried that the
    > type of the object will not be recognised when it reaches framework - I
    > am fine with sticking with const char* as an exception type if that's
    > the only reliable option, but a struct with a code, a message, and some
    > source information would be preferable, of course.
    >
    > Phew. I hope that's clear.
    >
    > Thanks in advance for any comments.
    > Ben Mitch


    I have studied this problem extensively in the context of dynamically
    generated C code. I will not bore you with the details, but solving
    the problem you see is not easy at all.

    1) Using Microsoft compiler will work if all the "clients" use also
    the same compiler AND the same version. With different versions of
    the compiler things could change and you would experience mysterious
    crashes.

    2) Avoid gcc if possible. There is no documentation almost about the
    exception framework and the documentation available is highly
    misleading. In any case if you have to use gcc you will want to
    ALWAYS use gcc ("clients" and API server) and specially, the SAME
    version of gcc. Do remember that gcc changes its behaviour from
    version to version without any announcement, since all this is
    not really documented.


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 13, 2008
    #2
    1. Advertising

  3. ben mitch <> writes:
    > I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    > immediately that the question *may* turn out to be
    > compiler-/os-specific, in which case I apologize. But I wonder if
    > there's an underlying truth.
    >

    [SNIP]
    >
    > Motivation: It would be convenient if the api could throw an exception
    > that the framework would recognise. It would pass painlessly up
    > through any user code without the user having to do anything, and the
    > framework could find out what happened and generate a useful error
    > report. The alternative is that we enforce that all API functions do
    > not throw and instead return error codes - the onus is then on the
    > plugin author to catch the error and return it to the framework (or,
    > if they are authoring in C++, they could throw an exception
    > themselves, but i'm not sure if that's not the same question again).

    [SNIP]

    I think this is really a question for comp.lang.c++, not for
    comp.lang.c (even though it does involve both languages. The C+
    standard defines features for interfacing to C, but C doesn't define
    any features for interfacing to C++. Furthermore, C says nothing
    about C++-style exceptions.

    I suspect that exception propagation across C code is system-specific,
    but the folks in comp.lang.c++ can probably give you more information
    on that point.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 13, 2008
    #3
  4. On 2008-06-13 15:07, ben mitch wrote:
    > Hi
    >
    > I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    > immediately that the question *may* turn out to be
    > compiler-/os-specific, in which case I apologize. But I wonder if
    > there's an underlying truth.
    >
    > We are writing a (cross-platform) 'framework' application (in C++, as it
    > happens) that allows users to author 'plugins' (as shared library
    > modules).


    If you want it to truly be cross-platform you can not allow exceptions
    to pass through to/from the plugins. The reason is simple: there is no
    standardised way of doing this. The only (?) standardised calling
    convention which will be available on multiple platforms is the C
    calling convention and it does not support exceptions.

    --
    Erik Wikström
    Erik Wikström, Jun 13, 2008
    #4
  5. On 2008-06-13 17:59, Erik Wikström wrote:
    > On 2008-06-13 15:07, ben mitch wrote:
    >> Hi
    >>
    >> I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    >> immediately that the question *may* turn out to be
    >> compiler-/os-specific, in which case I apologize. But I wonder if
    >> there's an underlying truth.
    >>
    >> We are writing a (cross-platform) 'framework' application (in C++, as it
    >> happens) that allows users to author 'plugins' (as shared library
    >> modules).

    >
    > If you want it to truly be cross-platform you can not allow exceptions
    > to pass through to/from the plugins. The reason is simple: there is no
    > standardised way of doing this. The only (?) standardised calling
    > convention which will be available on multiple platforms is the C
    > calling convention and it does not support exceptions.


    Sorry, I should mention that it is possible, but you would have to
    require that all the code (framework and plugins) is compiled with the
    same compiler and you will have to use a C++ API.

    --
    Erik Wikström
    Erik Wikström, Jun 13, 2008
    #5
  6. ben mitch

    jacob navia Guest

    Erik Wikström wrote:
    > On 2008-06-13 15:07, ben mitch wrote:
    >> Hi
    >>
    >> I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    >> immediately that the question *may* turn out to be
    >> compiler-/os-specific, in which case I apologize. But I wonder if
    >> there's an underlying truth.
    >>
    >> We are writing a (cross-platform) 'framework' application (in C++, as it
    >> happens) that allows users to author 'plugins' (as shared library
    >> modules).

    >
    > If you want it to truly be cross-platform you can not allow exceptions
    > to pass through to/from the plugins. The reason is simple: there is no
    > standardised way of doing this. The only (?) standardised calling
    > convention which will be available on multiple platforms is the C
    > calling convention and it does not support exceptions.
    >


    This is not true. Most C++ compilers support C and will allow C and
    C++ to coexist peacefully. Problems arise when you mix different
    compilers and versions or you want to generate code dynamically.



    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 13, 2008
    #6
  7. On 2008-06-13 18:04, jacob navia wrote:
    > Erik Wikström wrote:
    >> On 2008-06-13 15:07, ben mitch wrote:
    >>> Hi
    >>>
    >>> I hope you'll see this cross-post (c/c++) as appropriate. I also admit
    >>> immediately that the question *may* turn out to be
    >>> compiler-/os-specific, in which case I apologize. But I wonder if
    >>> there's an underlying truth.
    >>>
    >>> We are writing a (cross-platform) 'framework' application (in C++, as it
    >>> happens) that allows users to author 'plugins' (as shared library
    >>> modules).

    >>
    >> If you want it to truly be cross-platform you can not allow exceptions
    >> to pass through to/from the plugins. The reason is simple: there is no
    >> standardised way of doing this. The only (?) standardised calling
    >> convention which will be available on multiple platforms is the C
    >> calling convention and it does not support exceptions.
    >>

    >
    > This is not true. Most C++ compilers support C and will allow C and
    > C++ to coexist peacefully. Problems arise when you mix different
    > compilers and versions or you want to generate code dynamically.


    What is not true? To my knowledge there are two ways for C and C++ to
    coexist: either you compile the C code as C++ (in which case it is no
    longer C), or you use extern "C", in which case you use the C calling
    convention.

    Further mote it is true that there is no standardised cross-platform way
    of propagating exceptions. An, as far as I know, the C calling
    convention is the only wide-spread standardised calling convention.

    --
    Erik Wikström
    Erik Wikström, Jun 13, 2008
    #7
  8. ben mitch

    jacob navia Guest

    Erik Wikström wrote:
    > On 2008-06-13 18:04, jacob navia wrote:
    >> Erik Wikström wrote:
    >>> If you want it to truly be cross-platform you can not allow exceptions
    >>> to pass through to/from the plugins. The reason is simple: there is no
    >>> standardised way of doing this. The only (?) standardised calling
    >>> convention which will be available on multiple platforms is the C
    >>> calling convention and it does not support exceptions.
    >>>

    >> This is not true. Most C++ compilers support C and will allow C and
    >> C++ to coexist peacefully. Problems arise when you mix different
    >> compilers and versions or you want to generate code dynamically.

    >
    > What is not true? To my knowledge there are two ways for C and C++ to
    > coexist: either you compile the C code as C++ (in which case it is no
    > longer C), or you use extern "C", in which case you use the C calling
    > convention.
    >


    Calling conventions have nothing to do here. You are confusing calling
    convention (function call interface) with propagating the exceptions
    (i.e. letting a throw pass through your code), what is completely
    different.

    > Further mote it is true that there is no standardised cross-platform way
    > of propagating exceptions.


    Yes. That is why I said that if you stick to the same
    compiler and version it will work.

    > An, as far as I know, the C calling
    > convention is the only wide-spread standardised calling convention.
    >


    Again, calling conventions are NOT the issue here.

    jacob

    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 13, 2008
    #8
  9. ben mitch

    Ian Collins Guest

    jacob navia wrote:
    > Erik Wikström wrote:
    >> On 2008-06-13 15:07, ben mitch wrote:
    >>> Hi
    >>>
    >>> I hope you'll see this cross-post (c/c++) as appropriate. I also
    >>> admit immediately that the question *may* turn out to be
    >>> compiler-/os-specific, in which case I apologize. But I wonder if
    >>> there's an underlying truth.
    >>>
    >>> We are writing a (cross-platform) 'framework' application (in C++, as
    >>> it happens) that allows users to author 'plugins' (as shared library
    >>> modules).

    >>
    >> If you want it to truly be cross-platform you can not allow exceptions
    >> to pass through to/from the plugins. The reason is simple: there is no
    >> standardised way of doing this. The only (?) standardised calling
    >> convention which will be available on multiple platforms is the C
    >> calling convention and it does not support exceptions.
    >>

    >
    > This is not true. Most C++ compilers support C and will allow C and
    > C++ to coexist peacefully.


    They do, provided you use C linkage functions (extern "C" in the C++
    world). Exceptions are alien to C, so you simply can't propagate
    exceptions through a C function.

    > Problems arise when you mix different
    > compilers and versions or you want to generate code dynamically.
    >

    A problem in C++, but in C? The C ABI is determined by the platform,
    not the compiler (at least in the Linux/Unix world). If a compiler used
    a different ABI, how could it link to system libraries?

    --
    Ian Collins.
    Ian Collins, Jun 13, 2008
    #9
  10. ben mitch

    jacob navia Guest

    Ian Collins wrote:
    > jacob navia wrote:

    [snip]
    >> This is not true. Most C++ compilers support C and will allow C and
    >> C++ to coexist peacefully.

    >
    > They do, provided you use C linkage functions (extern "C" in the C++
    > world). Exceptions are alien to C, so you simply can't propagate
    > exceptions through a C function.
    >


    Yes you can. I have done this under gcc and msvc, and I think
    all C++ compilers will generate compatible code.

    >> Problems arise when you mix different
    >> compilers and versions or you want to generate code dynamically.
    >>

    > A problem in C++, but in C? The C ABI is determined by the platform,
    > not the compiler (at least in the Linux/Unix world). If a compiler used
    > a different ABI, how could it link to system libraries?
    >


    If you use different compilers, the throw machinery ill be different
    and passing throws will just not work.


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 13, 2008
    #10
  11. ben mitch

    Ian Collins Guest

    jacob navia wrote:
    > Ian Collins wrote:
    >> jacob navia wrote:

    > [snip]
    >>> This is not true. Most C++ compilers support C and will allow C and
    >>> C++ to coexist peacefully.

    >>
    >> They do, provided you use C linkage functions (extern "C" in the C++
    >> world). Exceptions are alien to C, so you simply can't propagate
    >> exceptions through a C function.
    >>

    >
    > Yes you can. I have done this under gcc and msvc, and I think
    > all C++ compilers will generate compatible code.
    >

    More by luck than anything else. The mechanics may work, but it's a
    very dangerous thing to do because the C code will not be exception
    aware, let alone safe.

    Like all things undefined, the next compiler release could break your code.

    >>> Problems arise when you mix different
    >>> compilers and versions or you want to generate code dynamically.
    >>>

    >> A problem in C++, but in C? The C ABI is determined by the platform,
    >> not the compiler (at least in the Linux/Unix world). If a compiler used
    >> a different ABI, how could it link to system libraries?
    >>

    >
    > If you use different compilers, the throw machinery ill be different
    > and passing throws will just not work.
    >

    Double check my post, I said "The C ABI is determined by the platform".
    C doesn't have throw machinery.

    --
    Ian Collins.
    Ian Collins, Jun 13, 2008
    #11
  12. ben mitch

    jacob navia Guest

    Ian Collins wrote:
    > jacob navia wrote:
    >> Ian Collins wrote:
    >>> jacob navia wrote:

    >> [snip]
    >>>> This is not true. Most C++ compilers support C and will allow C and
    >>>> C++ to coexist peacefully.
    >>> They do, provided you use C linkage functions (extern "C" in the C++
    >>> world). Exceptions are alien to C, so you simply can't propagate
    >>> exceptions through a C function.
    >>>

    >> Yes you can. I have done this under gcc and msvc, and I think
    >> all C++ compilers will generate compatible code.
    >>

    > More by luck than anything else. The mechanics may work, but it's a
    > very dangerous thing to do because the C code will not be exception
    > aware, let alone safe.
    >



    Who cares?

    C doesn't have to know any exceptions!

    The throw will pass through the C stack part until it finds a catch.
    Most compilers generate a set of tables describing the stack layout
    of each function so that the throw mechanism can walk the stack.

    If you compile with the same compiler, those tables get generated for
    the C code and you are in business.

    > Like all things undefined, the next compiler release could break your code.
    >


    I said that explicitely in my FIRST message. You need to keep
    compatible versions of everything:

    o The tables generated by the compiler
    o The throw run time mechanism


    >>>> Problems arise when you mix different
    >>>> compilers and versions or you want to generate code dynamically.
    >>>>
    >>> A problem in C++, but in C? The C ABI is determined by the platform,
    >>> not the compiler (at least in the Linux/Unix world). If a compiler used
    >>> a different ABI, how could it link to system libraries?
    >>>

    >> If you use different compilers, the throw machinery ill be different
    >> and passing throws will just not work.
    >>

    > Double check my post, I said "The C ABI is determined by the platform".
    > C doesn't have throw machinery.
    >


    You just do not know what the issue here is. Reread the OP
    message, and my answers. Obviously C doesn't have and doesn't
    need any throw machinery. That is not the issue here.


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 13, 2008
    #12
  13. ben mitch

    Ian Collins Guest

    jacob navia wrote:
    > Ian Collins wrote:
    >> jacob navia wrote:
    >>> Ian Collins wrote:
    >>>> jacob navia wrote:
    >>> [snip]
    >>>>> This is not true. Most C++ compilers support C and will allow C and
    >>>>> C++ to coexist peacefully.
    >>>> They do, provided you use C linkage functions (extern "C" in the C++
    >>>> world). Exceptions are alien to C, so you simply can't propagate
    >>>> exceptions through a C function.
    >>>>
    >>> Yes you can. I have done this under gcc and msvc, and I think
    >>> all C++ compilers will generate compatible code.
    >>>

    >> More by luck than anything else. The mechanics may work, but it's a
    >> very dangerous thing to do because the C code will not be exception
    >> aware, let alone safe.
    >>

    > Who cares?
    >

    Anyone who wants to write reliable, portable code.

    > C doesn't have to know any exceptions!
    >

    Isn't that what I said?

    > The throw will pass through the C stack part until it finds a catch.
    > Most compilers generate a set of tables describing the stack layout
    > of each function so that the throw mechanism can walk the stack.
    >

    Yes, so a C function calling a C++ function that throws will return at
    the point of the call, bypassing any clean up and possibly leaving the
    applications state in an undefined state. For example:

    void f()
    {
    allocateSomething(); /* 1 */

    callFunctionThatThrows(); /* 2 */

    deallocateSomthing(); /* 3 */
    }

    The function will "return" at line 2, line 3 will never be called.

    > If you compile with the same compiler, those tables get generated for
    > the C code and you are in business.
    >

    That forces you to compile C as C++. C isn't C++.

    >> Like all things undefined, the next compiler release could break your
    >> code.
    >>

    >
    > I said that explicitely in my FIRST message. You need to keep
    > compatible versions of everything:
    >
    > o The tables generated by the compiler
    > o The throw run time mechanism
    >

    You also appear to be implying that the C code be compiled as C++.
    >
    >>>>> Problems arise when you mix different
    >>>>> compilers and versions or you want to generate code dynamically.
    >>>>>
    >>>> A problem in C++, but in C? The C ABI is determined by the platform,
    >>>> not the compiler (at least in the Linux/Unix world). If a compiler
    >>>> used
    >>>> a different ABI, how could it link to system libraries?
    >>>>
    >>> If you use different compilers, the throw machinery ill be different
    >>> and passing throws will just not work.
    >>>

    >> Double check my post, I said "The C ABI is determined by the platform".
    >> C doesn't have throw machinery.
    >>

    > You just do not know what the issue here is. Reread the OP
    > message, and my answers.
    >

    To quote from the OP:

    framework::main() (C++)
    --> plugin::Event() (C)
    --> api::Sum() (C++)
    throw X;

    Which is exactly what the issue we should be discussing.

    > Obviously C doesn't have and doesn't
    > need any throw machinery. That is not the issue here.
    >

    Then why did you say mention throw machinery in response to a question
    about the C ABI?

    --
    Ian Collins.
    Ian Collins, Jun 13, 2008
    #13
  14. ben mitch

    ben mitch Guest

    It seems to me a fair summary, then, to say it's unwise for us to go
    this way. It might work under some conditions, but with no restrictions
    on compiler or even language..., and especially given my inexperience in
    this area. I guess we'll elect to use error codes instead, I can come to
    terms with that.

    Thanks, all, for your time and your helpful comments.
    ben mitch, Jun 14, 2008
    #14
  15. ben mitch

    jacob navia Guest

    Ian Collins wrote:
    [snip]

    Mr Collins

    1) The question here is if C and sit in the middle between a catch in
    C++ and a throw in C++. My answer is YES.

    2) If you leave objects without proper cleanup in your C code is
    another problem. HINT: Do not do that in your C code. Just never
    call a C++ function that can throw if you need to cleanup.

    3) In the case of the original poster of this thread everything is
    done at compile time. I have solved a more difficult case when
    in the framework of a JIT (Just in time compiler) you generate
    code dynamically. In the OP case there is no need to modify
    the C code. Obviously if any throw happens, cleanup may never
    happen. That is another problem. The question was if this is
    at all possible.

    I think your opinion and mine are well known. I stop this thread
    then.

    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jun 14, 2008
    #15
  16. ben mitch

    Ian Collins Guest

    jacob navia wrote:
    > Ian Collins wrote:
    > [snip]
    >
    > Mr Collins
    >
    > 1) The question here is if C and sit in the middle between a catch in
    > C++ and a throw in C++. My answer is YES.
    >

    And mine is NO. The result is undefined.

    My apologies to the c.l.c readers, but here's an example that
    illustrates this:

    x.cc:

    extern "C" void f();
    extern "C" void functionThatThrows() { throw 42; }

    int main ()
    {
    try { f(); }
    catch(...) {}

    return 0;
    }

    x.c:

    #include <stdio.h>

    void functionThatThrows();

    void f()
    {
    puts("allocateSomething");
    functionThatThrows();
    puts("deallocateSomthing");
    }

    With compiler A:

    c99 -c -o xc.o /tmp/x.c
    CC /tmp/x.cc xc.o

    ../a.out
    allocateSomething

    With compiler B:

    gcc -c -o xc.o /tmp/x.c
    g++ /tmp/x.cc xc.o

    ../a.out
    allocateSomething
    terminate called after throwing an instance of 'int'
    Abort (core dumped)

    > 2) If you leave objects without proper cleanup in your C code is
    > another problem. HINT: Do not do that in your C code. Just never
    > call a C++ function that can throw if you need to cleanup.
    >

    That assumes you know you are calling a C++ function.

    >
    > I think your opinion and mine are well known. I stop this thread
    > then.
    >

    Indeed. One of us understands the meaning of undefined behaviour and
    how to write portable code.

    --
    Ian Collins.
    Ian Collins, Jun 14, 2008
    #16
  17. ben mitch

    James Kanze Guest

    On Jun 14, 1:57 am, Ian Collins <> wrote:
    > jacob navia wrote:
    > > Ian Collins wrote:
    > > [snip]


    > > Mr Collins


    > > 1) The question here is if C and sit in the middle between a
    > > catch in C++ and a throw in C++. My answer is YES.


    > And mine is NO. The result is undefined.


    According to the standard. One thing an implementation can do
    with undefined behavior is define it; all of the C++ compilers I
    know do define it.

    Not that it's much use, of course. As you correctly pointed
    out, code written in C will not be exception safe; it counts on
    the guarantee (valid in C) that if you call a function, it
    either returns, or the process is aborted in some way.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 14, 2008
    #17
  18. ben mitch

    Lew Pitcher Guest

    In comp.lang.c, James Kanze wrote:
    [snip]
    > Not that it's much use, of course. As you correctly pointed
    > out, code written in C will not be exception safe; it counts on
    > the guarantee (valid in C) that if you call a function, it
    > either returns, or the process is aborted in some way.


    Hmmm....... So, what does longjmp() do? If you call a function that calls
    longjmp(), does the called function return? Or does longjmp() abort the
    process? (assuming that setjmp() was properly invoked prior to the call to
    the function)

    --
    Lew Pitcher

    Master Codewright & JOAT-in-training | Registered Linux User #112576
    http://pitcher.digitalfreehold.ca/ | GPG public key available by request
    ---------- Slackware - Because I know what I'm doing. ------
    Lew Pitcher, Jun 14, 2008
    #18
  19. ben mitch

    Ian Collins Guest

    James Kanze wrote:
    > On Jun 14, 1:57 am, Ian Collins <> wrote:
    >> jacob navia wrote:
    >>> Ian Collins wrote:
    >>> [snip]

    >
    >>> Mr Collins

    >
    >>> 1) The question here is if C and sit in the middle between a
    >>> catch in C++ and a throw in C++. My answer is YES.

    >
    >> And mine is NO. The result is undefined.

    >
    > According to the standard. One thing an implementation can do
    > with undefined behavior is define it; all of the C++ compilers I
    > know do define it.
    >

    True, but we were talking portable solutions here, so no is the only
    safe answer.

    Every compiler I use has its own exception propagation mechanism,
    ranging from the elegant to the gross. As an internal implementation
    detail, this is likely to change between releases. Thus even code built
    and "working" with the same tool chain is likely to break if the tools
    are upgraded.

    --
    Ian Collins.
    Ian Collins, Jun 15, 2008
    #19
  20. ben mitch

    James Kanze Guest

    On Jun 15, 1:16 am, Ian Collins <> wrote:
    > James Kanze wrote:
    > > On Jun 14, 1:57 am, Ian Collins <> wrote:
    > >> jacob navia wrote:
    > >>> Ian Collins wrote:
    > >>> [snip]


    > >>> Mr Collins


    > >>> 1) The question here is if C and sit in the middle between a
    > >>> catch in C++ and a throw in C++. My answer is YES.


    > >> And mine is NO. The result is undefined.


    > > According to the standard. One thing an implementation can do
    > > with undefined behavior is define it; all of the C++ compilers I
    > > know do define it.


    > True, but we were talking portable solutions here, so no is the only
    > safe answer.


    > Every compiler I use has its own exception propagation
    > mechanism, ranging from the elegant to the gross. As an
    > internal implementation detail, this is likely to change
    > between releases. Thus even code built and "working" with the
    > same tool chain is likely to break if the tools are upgraded.


    Yes. It's clear that all of the code must have been compiled
    with the same compiler (same version, and possibly even with the
    same options).

    If all the code is your application, you should have no trouble
    mastering this, and I wouldn't worry too much about portability.
    For things like plugins, of course, it's totally a different
    matter, and if your plugin uses a C ABI, you certainly cannot
    count on exceptions propagating through it (and if it uses a C++
    ABI, of course, the suppliers of the plugin will have to compile
    with the same compiler---including version and options enought
    to ensure binary compatibility---or the plugin won't work).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 15, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Harrison

    pass char* over dll-boundaries

    John Harrison, Sep 3, 2004, in forum: C++
    Replies:
    8
    Views:
    781
  2. foxx
    Replies:
    4
    Views:
    440
  3. ben mitch
    Replies:
    22
    Views:
    825
    Chris Dollin
    Jun 16, 2008
  4. Ò»Ê×Ê«

    Passing string over DLL boundaries.

    Ò»Ê×Ê«, Aug 24, 2008, in forum: C++
    Replies:
    4
    Views:
    407
    Juha Nieminen
    Aug 24, 2008
  5. r
    Replies:
    5
    Views:
    181
    Kent Johnson
    Apr 9, 2011
Loading...

Share This Page