Re: [Boost-bugs] [Boost C++ Libraries] #754: boost::any - typeid comparison across shared boundaries

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