From: Alexander Grund (alexander.grund_at_[hidden])
Date: 2019-12-17 07:36:13
On 16.12.19 23:43, Gavin Lambert via Boost wrote:
> This is why, as I mentioned elsewhere in a related context, macros
> should only ever select between different explicitly-named-differently
> implementations (such as setting a default for that template policy
> parameter, but not replacing the template policy parameter).
> Otherwise you get ODR violations and inconsistent ABI.Â At least when
> explicitly part of the signature, both implementations can co-exist in
> the same binary with minimal issues as long as they're kept strictly
> separate -- and if someone tries to "cross the streams" then they'll
> get linker errors.
> Or, as I also said elsewhere, just pick one and stick to your guns.
> Personally, I prefer throwing exceptions for that case; it's much
> safer than allowing a buffer overflow.
+1 to the whole. Having macros to select default template params avoids
the ODR and mixing issues. HOWEVER: What about you set
BOOST_USE_THROW=1, then include libraryX then Boost and then use
`static_string<char/*, default chosen by macro*/>`? libraryX might
redefine BOOST_USE_THROW=0 and you get the wrong type.
So IMO either template policy (only) or "stick to your guns".
I'm also pro-exception on "overflow". Often enough (especially in hot
loops where bounds are usually clear) the optimizer will remove all those.
At least, just std::abort.
> +1. Although throw_exception itself is not entirely immune to the
> problems above, it is at least a customisation point that only the
> application author is allowed to touch, which is better than a macro.
> [Although things get a bit dicier with shared objects and private
Oh yes... Damn shared objects. And with boost::throw_exception opens the
door for ODR violations again...