Boost logo

Boost :

From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2021-02-02 11:59:15


On 2/2/21 2:51 PM, Andrey Semashev wrote:
> 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.

PPS: I forgot to add that recent gcc versions don't need RTTI to be
publicly visible to be able to catch exceptions or compare type_info, as
they now perform deep string comparison instead of address comparison.
However, older compiler versions are still susceptible to this, and I'm
not sure if the deep comparison behavior is used on all platforms.


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