GNOME Bugzilla – Bug 101455
Exceptions not defined - where is the problem?
Last modified: 2004-12-22 21:47:04 UTC
pass_gather.cc contains this code: g_warning ("%s can throw exceptions of type " "%s, but it's not defined", op->get_cpp_typename ().c_str (), idlGetQualIdentifier (IDL_LIST (raises_list).data).c_str ()); But it's not clear where the fault lies, or what needs to be corrected. This leads to warnings while building libbonobomm: ** (process:31687): WARNING **: ::Bonobo::Moniker::resolve can throw exceptions of type ::Bonobo::GeneralError, but it's not defined
Gergo said: This warning is shown when a method in an interface is declared to throw an exception that isn't defined. ORBit itself should pick up undeclared exceptions, but it's more complicated with undefined ones. The problem is, with the C++ bindings you need the definition of the stub for the exception to be able to throw them. You may look at Bonobo_Moniker.idl and trace its #include statements and realize that it does, indeed, include the definition of Bonobo::GeneralError. However, it's inside an "inhibit" block, which means its definition is not included in the IDL compiler's state, only its declaration. I hope that helps clear up the issue. As for how to solve it, I haven't thought about it yet, at the time I was writing that code, I just wanted to get something out that worked most of the time and leave the hard parts later.
I think I understand what is going on. The inhibit block is so that the definitions can be generated and compiled into the libbonobo library and from then on code that makes use of bonobo will only get declarations out of the idl compiler. Then the client code links against the definitions in libbonobo. This means that the Exceptions need to appear in the throw specification and in the translation between C and C++ even though they aren't defined. The generated code has to assume that they will be defined somewhere. I'll try and fix this soon, but it will probably be a week or so. So this is definitely a bug in orbitcpp. But, by the above reasoning that the bug is being evidenced in the compilation of libbonobomm would indicate a problem in libbonobomm. Since all the definitions should be generated for libbonobomm and C++ code that uses bonobo should get the definitions by linking. So I think that there should be extra defines in the libbonobomm/bonobomm/generated/Makefile.am: -D__Bonobo_GenericFactory_COMPILATION -D__Bonobo_Activation_types_COMPILATION Also rather than generate the C stubs/skels and compile that, I think libbonobomm should be linking against the installed libbonobo. Murray what do you think?
Thanks for making some sense of this. I will try to give it fuller attention sometime. > -D__Bonobo_GenericFactory_COMPILATION > -D__Bonobo_Activation_types_COMPILATION I haven't seen these before. I will try to investigate. > Also rather than generate the C stubs/skels and compile that, I think > libbonobomm should be linking against the installed libbonobo. Yes, we should try that.
This problem also occurs for interfaces as reported by Robert Melby (async@cc.gatech.edu): #pragma inhibit push module foo { interface bar { }; }; #pragma inhibit pop module B { interface C { ::foo::bar get_foo(); }; };
I have committed some groundwork for fixing this bug. See ChangeLog entry: 2003-10-02 Bowie Owens <bowie.owens@csiro.au>. It resolves the problems with interfaces reported by Robert Melby. Exceptions are a bit trickier. I'll try and get onto it soon.
From ChangeLog: Added IDLThrowable interface as a common base class for defined and inhibited exceptions. Implemented IDLInhibitedException using IDLInhibited. Replaced warning about undefined exception with use of IDLInhibitedException.
Just realised this problem of inhibited definitions runs a bit deeper, so I have reopened this bug. The changes I have made so far fix the problems with inhibited exceptions and interfaces. Unfortunately, types.cc doesn't discriminate the kind of ident so the following will think that foo::Integer and foo::S are interfaces and thus generate bad code for B::C. #pragma inhibit push module foo { typedef long Integer; struct S { long i; }; interface bar { }; exception eep { }; }; #pragma inhibit pop module B { interface C { foo::bar get_foo() raises (foo::eep); foo::S the_s(); foo::Integer the_integer(); }; };
Major rehaul required but this should be fixed now.