On 02/02/2021 14:43, Alexander Grund via Boost wrote:
It is marked with BOOST_SYMBOL_VISIBLE, so we seem to agree, that this is required for all user visible classes that are errors/exceptions or virtual (and hence might be subject to dynamic_cast)
You're right, in the very strict sense, that any vptr containing class would need to be BOOST_SYMBOL_VISIBLE to ensure dynamic_cast works. Far better though, in my opinion, to replace all dynamic_cast with static_cast, and don't mark all vptr containing classes as always visible. This is because there are real problems with link times, ABI collision and poor codegen with BOOST_SYMBOL_VISIBLE. Those impact all users far more frequently than dynamic_cast, which nobody should be using in any case. As I've already mentioned, if you really want dynamic_cast to always work, don't use -fvisibility=hidden. Easy.
Hidden symbols are subject to much more aggressive optimisation than default visibility symbols. So yes, this is intentional.
I'm aware of that. But I'm looking for a correct solution, i.e. one that works across platforms. That it seemingly works on Linux seems to be caused by a change to string comparison instead of "real" RTTI comparison. The question is: Should it work, or has it always worked? I mean we have one TU (in the shared lib) where the symbol is visible and one (in the exe) where it is not. So how could the RTTI here be the same?
I don't think it is for library authors to force semantics onto users in this area. If an end user asks for -fvisibility=hidden, they opt into everything that entails, footguns and all. All the library author can do is a best effort to not screw things up within their library if end users enable that. Most Boost libraries clearly document whether they depend on RTTI or not. If they do, you can't use either -fvisibility=hidden nor -fno-rtti. It would be super nice if Boost.Build automatically detected -fno-rtti and -fvisibility=hidden and simply did not compile those libraries which claim they require RTTI, but we need that metadata json thingy working first. Niall