Subject: Re: [Boost-bugs] [Boost C++ Libraries] #754: boost::any - typeid comparison across shared boundaries
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2007-08-29 14:28:14
#754: boost::any - typeid comparison across shared boundaries
--------------------+-------------------------------------------------------
Reporter: kulik | Owner: nasonov
Type: Bugs | Status: new
Milestone: | Component: any
Version: None | Severity: Problem
Resolution: None | Keywords:
--------------------+-------------------------------------------------------
Changes (by marshall):
* component: None => any
Old description:
> {{{
> typeid comparison (using == operator) fails under
> certain platforms and certain conditions. For me it
> fails for template classes at least (std::vector for
> example) when I use it across shared boundaries.
> Therefore boost::any doesn't work in these cases and
> throws bad_any_cast exception even when it returns it
> holds the same type I am about to cast it to (I am
> using gcc-4.1).
>
> boost::python has already solved this by comparing
> string representations of types under problematic
> platforms. This works well in all cases but can be a
> bit slower.
>
> In boost/python/type_id.hpp:
> // for this compiler at least, cross-shared-library
> type_info
> // comparisons don't work, so use typeid(x).name()
> instead. It's not
> // yet clear what the best default strategy is.
> # if (defined(__GNUC__) && __GNUC__ >= 3) \
> || defined(_AIX) \
> || ( defined(__sgi) && defined(__host_mips)) \
> || (defined(linux) && defined(__INTEL_COMPILER) &&
> defined(__ICC))
> # define BOOST_PYTHON_TYPE_ID_NAME
> # endif
>
> I would say the same thing should be applied to boost::any
>
> In boost/any.hpp:
> template<typename ValueType>
> ValueType * any_cast(any * operand)
> {
> return operand && operand->type() == typeid(ValueType)
> ? &static_cast<any::holder<ValueType>
> *>(operand->content)->held
> : 0;
> }
>
> should be replaced with:
>
> template<typename ValueType>
> ValueType * any_cast(any * operand)
> {
> # if (defined(__GNUC__) && __GNUC__ >= 3) \
> || defined(_AIX) \
> || ( defined(__sgi) && defined(__host_mips)) \
> || (defined(linux) && defined(__INTEL_COMPILER) &&
> defined(__ICC))
> return operand && !strcmp( operand->type().name(),
> typeid(ValueType).name()
> ? &static_cast<any::holder<ValueType>
> *>(operand->content)->held
> : 0;
> # else
> return operand && operand->type() == typeid(ValueType)
> ? &static_cast<any::holder<ValueType>
> *>(operand->content)->held
> : 0;
> # endif
> }
>
> btw: I am aware that this may cause performance drops
> and it would be great if there was a switch for that or
> something for people that aren't using boost::any
> across shared boundaries.
>
> }}}
New description:
{{{
typeid comparison (using == operator) fails under
certain platforms and certain conditions. For me it
fails for template classes at least (std::vector for
example) when I use it across shared boundaries.
Therefore boost::any doesn't work in these cases and
throws bad_any_cast exception even when it returns it
holds the same type I am about to cast it to (I am
using gcc-4.1).
boost::python has already solved this by comparing
string representations of types under problematic
platforms. This works well in all cases but can be a
bit slower.
In boost/python/type_id.hpp:
// for this compiler at least, cross-shared-library
type_info
// comparisons don't work, so use typeid(x).name()
instead. It's not
// yet clear what the best default strategy is.
# if (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips)) \
|| (defined(linux) && defined(__INTEL_COMPILER) &&
defined(__ICC))
# define BOOST_PYTHON_TYPE_ID_NAME
# endif
I would say the same thing should be applied to boost::any
In boost/any.hpp:
template<typename ValueType>
ValueType * any_cast(any * operand)
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType>
*>(operand->content)->held
: 0;
}
should be replaced with:
template<typename ValueType>
ValueType * any_cast(any * operand)
{
# if (defined(__GNUC__) && __GNUC__ >= 3) \
|| defined(_AIX) \
|| ( defined(__sgi) && defined(__host_mips)) \
|| (defined(linux) && defined(__INTEL_COMPILER) &&
defined(__ICC))
return operand && !strcmp( operand->type().name(),
typeid(ValueType).name()
? &static_cast<any::holder<ValueType>
*>(operand->content)->held
: 0;
# else
return operand && operand->type() == typeid(ValueType)
? &static_cast<any::holder<ValueType>
*>(operand->content)->held
: 0;
# endif
}
btw: I am aware that this may cause performance drops
and it would be great if there was a switch for that or
something for people that aren't using boost::any
across shared boundaries.
}}}
--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/754#comment:5>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:56 UTC