Opened 16 years ago
Last modified 13 years ago
#754 closed Bugs (fixed)
boost::any - typeid comparison across shared boundaries — at Initial Version
| Reported by: | kulik | Owned by: | alnsn |
|---|---|---|---|
| Milestone: | Component: | any | |
| Version: | None | Severity: | Problem |
| Keywords: | Cc: |
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.
Note:
See TracTickets
for help on using tickets.
