On Thursday 01 May 2014 21:02:14 Antony Polukhin wrote:
2014-05-01 13:07 GMT+04:00 Andrey Semashev
: On Wednesday 30 April 2014 19:40:54 Antony Polukhin wrote:
I see your point. Let's try to resolve this somehow without throwing away the BOOST_TYPE_INDEX_USER_TYPEINDEX macro.
Is in your case type_index one of the function arguments? If yes - then user won't be able to link modules with and without BOOST_TYPE_INDEX_USER_TYPEINDEX. Linker won't find functions.
Currently, in some cases std::type_info is the argument. If type_index is the argument in those cases, linker errors will protect from crashes in run time. But these functions are not always used by the application, so it's not a 100% protection.
In other cases std::type_info const* is stored in structures and containers thereof, and do not affect mangled type and function names. I'll have to inspect the code to see if Boost.Log actually has these cases but it certainly does not prohibit them; they may appear in user's code as well.
I know there are workarounds for this. Like add yet another tag to Boost.Log internal namespace. (BTW, using a function is not really a good solution because this function needs to be called in many places of the code; it reduces efficiency, introduces false dependency on the binary, and is easy to miss). But these are workarounds that are not needed now and required to support a controversial feature. With Boost.Log's internal namespace the workaround may seem easy to implement, but other libraries don't have such a namespace, and there the fix would not be so easy.
Can we make somehow such link-time assertion in TypeIndex library itself (extern variable, function...)? I have no good ideas right now, but I'm almost certain that it is possible.
I honestly can't think of one, unless Boost.TypeIndex has a compiled part, which I think is not acceptable. Another solution would be to mangle boost namespace name but that is hardly doable since this would affect all libraries.
In that header, I can see the code that works around the problem by using template specializations. As I understand, the compiler matches specializations for int when the template is instantiated for signed int. Why not make the same workaround in Boost.TypeIndex? The case is very much the same.
I do not have any will to add many overloads to fix an antique compiler that even can not be tested. How about a following workaround for those compilers:
typename boost::mpl::if_< boost::is_signed
, boost::make_signed , boost::mpl::identity ::type::type res_t;
And then use typeid(res_t)? Yes, that'd be ok, but it's better to do it like
this:
typename mpl::eval_if<
mpl::and_<
is_integral
::type res_t;
At least MSVC 7.1 has problems applying is_signed to non-integral types, not sure about those EDG compilers, but it's better to be on the safe side. Of course that code is only needed for the old EDG compilers.