Boost logo

Boost :

Subject: Re: [boost] bug-sprint #2114, 2 comments
From: Alexander Arhipenko (arhipjan_at_[hidden])
Date: 2009-06-10 08:03:43


On Wed, Jun 10, 2009 at 11:04 AM, Juergen
Hunold<juergen.hunold_at_[hidden]> wrote:
>
[snip]
> That means "__attribute__((visibility("default")))", right ?
Yes, exactly

[snip]
>
>> Oh, now I am confused. How exactly those symbols are to be used?
>> Say, I declare an exception class in a header -- what modifiers
>> should I use? Do we need BOOST_WHATEVER_EXCEPTION_DECL? Maybe
>> you can write up some guidance for library authors?
>
> Yeah, me too ;-))
> That whole exception export thing is quite a miracle.
>
In response to above:
I have written down 2 sample configuration files for the 'foo' library.

#if !defined BOOST_FOO_DETAIL_CONFIG_HPP
#define BOOST_FOO_DETAIL_CONFIG_HPP

#if defined BOOST_FOO_BUILD_SHLIB
# define BOOST_FOO_DECL BOOST_SYMBOL_EXPORT
# define BOOST_FOO_EXCEPTION_DECL BOOST_EXCEPTION_EXPORT
#elif defined BOOST_FOO_USE_SHLIB
# define BOOST_FOO_DECL BOOST_SYMBOL_IMPORT
# define BOOST_FOO_EXCEPTION_DECL BOOST_EXCEPTION_IMPORT
#else
# define BOOST_FOO_DECL
# define BOOST_FOO_EXCEPTION_DECL
#endif

#endif

Configuration file above will re-export all the exceptions marked with
BOOST_FOO_EXCEPTION_DECL from shared library foo.
So, if I write library 'bar', it will contain all the symbols exported by 'bar'
and also all the exceptions from 'foo' library'.
This is intended for the following scenario:

exe test : main.cpp bar ;

main.cpp:

#include <bar.hpp>
#include <foo/error.hpp>

int main()
{
   try
   {
      bar::function();//could potentially throw foo's exception
   }
   catch(const foo::error& e)
   {
      std::cerr<<"error occured: "<<e.what()<<'\n';
   }

   return 0;
}

In case if 'bar' reexports exceptions from 'foo', the code above will succeed.
Otherwise it will be aborted, since foo::error won't be caught.

But, all these could be not enough for the sophisticated user.
Assume, library 'bar' will use library 'foo' as an implementation detail
and also will catch all the foo's exceptions. So, bar's maintainer doesn't want
to re-export foo's stuff from his library. As a result, foo's
maintainer should provide
more sophisticated configuration file (I marked changes with '+'):

 #if !defined BOOST_FOO_DETAIL_CONFIG_HPP
 #define BOOST_FOO_DETAIL_CONFIG_HPP

#if defined BOOST_FOO_BUILD_SHLIB
# define BOOST_FOO_DECL BOOST_SYMBOL_EXPORT
# define BOOST_FOO_EXCEPTION_DECL BOOST_EXCEPTION_EXPORT
#elif defined BOOST_FOO_USE_SHLIB
# define BOOST_FOO_DECL BOOST_SYMBOL_IMPORT
+# if defined BOOST_FOO_EXCEPTION_REEXPORT
# define BOOST_FOO_EXCEPTION_DECL BOOST_EXCEPTION_IMPORT
+# else
+# define BOOST_FOO_EXCEPTION_DECL BOOST_SYMBOL_IMPORT
+# endif
#else
# define BOOST_FOO_DECL
# define BOOST_FOO_EXCEPTION_DECL
#endif

#endif

So, now bar library maintener have a choice:
1. Re-export foo's exceptions and let them left the bar library's boundaries
2. Catch all the foo's exceptions, process and do not re-export

P.S.
I've attached minimal bbv2 project that reproduce the problem
with uncaught exception. To eliminate it, you can do the following:
a) Replace FOO_DECL with FOO_EXCEPTION_DECL in Error class declaration
b) Uncomment ~Error() declaration (foo/error.hpp) and definition (foo/foo.cpp)




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk