|
Boost : |
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2021-02-02 11:51:33
On 2/2/21 11:35 AM, Alexander Grund via Boost wrote:
> Hi Boost maintainers,
>
> TLDR: Check your classes if they use BOOST_*_DECL and change that to
> BOOST_SYMBOL_VISIBLE
>
>
> In Boost.ProgramOptions I discovered an issue as a user, where I was
> unable to catch an exception thrown from the shared Boost library in an
> executable when both are build with hidden visibility.
>
> It turns out the exception class was marked with
> BOOST_PROGRAM_OPTIONS_DECL which evaluates to "visible" when building
> the DLL but to nothing when using it.
> This makes the linker (in theory) mark the typeinfo as hidden which
> means that the class thrown by Boost and the one tried to catch are
> unrelated.
This means that BOOST_PROGRAM_OPTIONS_DECL is incorrectly defined.
The basic gist is as follows:
1. On Windows, there is no visibility support. gcc and clang still
support visibility attributes (including BOOST_SYMBOL_VISIBLE), but I
don't think they have any effect. On Windows, you should be using
BOOST_SYMBOL_EXPORT/BOOST_SYMBOL_IMPORT, depending on when your library
is compiled or when user's code is compiled.
2. Again, on Windows, there is no need to export/import RTTI for it to
work, so you don't need to mark exceptions just to make them catchable.
You may still want to export/import a class (including an exception) if
you want to export/import all its methods, *including the implicitly
generated ones*. In particular, the compiler will probably not inline
any methods of the class, so it is more preferable to mark individual
methods rather than the whole class.
3. On other systems, where visibility is supported, BOOST_SYMBOL_VISIBLE
must be used both when compiling the library and user's code, and it
should be used to mark types whose RTTI is required to work across
library boundaries. This includes exceptions and types that participate
in dynamic_cast. Also, BOOST_SYMBOL_VISIBLE must be used to
export/import methods from the library.
So, the bottom line, BOOST_PROGRAM_OPTIONS_DECL must be defined to:
- BOOST_SYMBOL_EXPORT - on Windows, when the library is being built;
- BOOST_SYMBOL_IMPORT - on Windows, when the library is being consumed
by user;
- BOOST_SYMBOL_VISIBLE - in any other case.
Then you can use BOOST_PROGRAM_OPTIONS_DECL to mark methods and classes
that you want to be exported/imported from the library. If a particular
type does not need to be exported/imported, but whose RTTI must still be
accessible across library boundaries, mark that type with
BOOST_SYMBOL_VISIBLE, not BOOST_PROGRAM_OPTIONS_DECL. You can still use
BOOST_PROGRAM_OPTIONS_DECL to export/import select methods of that type,
if needed.
PS: I remember someone saying that on recent Windows dllexport/dllimport
attributes are no longer necessary. I don't quite know how that works,
but for backward compatibility we should probably keep using
BOOST_SYMBOL_EXPORT/BOOST_SYMBOL_IMPORT as described above.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk