Archived

This forum has been archived. Please start a new discussion on GitHub.

Exception reordering in C++ interface

slice2cpp creates cpp files where the exceptions which are caught and thrown/marshalled are not in the same order as they are in the .ice file.

i created the following example code to illustrate my problem:
module bla {

        exception Parent {};
        exception Child extends Parent {};
        exception XChild extends Parent {};

        interface bli {
                void testi1() throws Parent, Child;
                void testi2() throws Child, Parent;
                void testi3() throws Parent, XChild;
                void testi4() throws XChild, Parent;
        };

};

the cpp file created by slice2cpp contains instructions to catch _each_ of the exceptions thrown by a method.

the problem is, they are caught in alphabetical order, thus i get the following warnings from g++ if i try to compile the generated files:
test_exception_throwing.cpp: In member function `IceInternal::DispatchStatus 
   bla::bli::___testi3(IceInternal::Incoming&, const Ice::Current&)':
test_exception_throwing.cpp:859: warning: exception of type `bla::XChild' will 
   be caught
test_exception_throwing.cpp:854: warning:    by earlier handler for `
   bla::Parent'
test_exception_throwing.cpp: In member function `IceInternal::DispatchStatus 
   bla::bli::___testi4(IceInternal::Incoming&, const Ice::Current&)':
test_exception_throwing.cpp:880: warning: exception of type `bla::XChild' will 
   be caught
test_exception_throwing.cpp:875: warning:    by earlier handler for `
   bla::Parent'

i think the exceptions are ordered alphabetically in the try{ } catch()... block generated by slice2cpp.

is this done deliberate?

the problem is that XChild will never be caught from a calling function because the exception will never be marshalled because all such exceptions will be interpreted as Parent

i think the order should be the same as given by the programmer.

in my example .ice code, this would mean that the methods testi1 and testi3 would give the warning, but it _would_ be possible to remove the warnings by manually reordering the exceptions.

with an alphabetical sorting, it is not possible to remove the warnings by reordering, the exceptions would have to be renamed.

edit: removed smilies in code

Comments

  • mes
    mes California
    Re: Exception reordering in C++ interface
    Originally posted by peter.s
    i think the exceptions are ordered alphabetically in the try{ } catch()... block generated by slice2cpp.

    is this done deliberate?
    No, this is simply an oversight on our part.
    the problem is that XChild will never be caught from a calling function because the exception will never be marshalled because all such exceptions will be interpreted as Parent
    The caller will still receive the proper exception, because exceptions are marshaled using a virtual function. In other words, even if the exception handler for Parent is invoked, the caller will still receive XChild.
    i think the order should be the same as given by the programmer.
    There are at least two ways we could handle this issue. One is to treat it as a coding style issue and formally recommend against (or have the translator prevent) declaring "duplicate" exceptions in an operation, where "duplicate" means the inclusion of base and derived exceptions. Technically, it's only necessary to list the base exception, since the operation is always allowed to raise derived exceptions without explicitly specifying each one. Of course, the receiver may not be able to unmarshal all of the derived exceptions, but that's a separate issue.

    The other approach is to modify the code generator so that it avoids these warnings.

    My colleagues and I will have to discuss this issue, and then I'll post the outcome.

    Thanks,
    - Mark
  • I'd be inclined to fix the code generator. Even though having both a base and a derived exception in an exception specification is pointless, I'd follow the precedent set by C++ and continue to allow this. We just need to make sure that the most-derived exception appear before any base exceptions in the catch blocks.

    Cheers,

    Michi.
  • hm, fixing the code generator to honour the exception hierarchy would be one way to fix it, fixing it to hounor the programmers exception order would be the second way ....

    personally, i think it's easier and perhaps more intuitively to keep the ordering as the programmer specified it - this way you don't need to go through the exception hierarchy tree too :-)

    thanks for the fast answer :-)
    Peter

    edit: but automatic reordering would be more comfortable for sure :-)
  • Originally posted by peter.s
    hm, fixing the code generator to honour the exception hierarchy would be one way to fix it, fixing it to hounor the programmers exception order would be the second way ....

    personally, i think it's easier and perhaps more intuitively to keep the ordering as the programmer specified it - this way you don't need to go through the exception hierarchy tree too :-)

    Well, the order in which exceptions appear in an exception specification is irrelevant to the semantics of a method in both Java and C++, so I'd rather not attach semantics to the order for Slice excepton specifications.

    Changing the code generator to arrange the catch blocks in most-derived to least-derived order is more work, but will fix the problem permanently, without the possibility of further surprises. (In general, any Slice specification that compiles must also generate correct code. Clearly, if we depend on the order chosen by the programmer, that wouldn't be the case.)

    Cheers,

    Michi.
  • I've changed the parser to order the exceptions correctly.
    You can pick up a patch in the Patches forum:

    www.zeroc.com/vbulletin/showthread.php?s=&threadid=496

    Cheers,

    Michi.
  • thank you very much, the patch works perfectly :)

    Peter