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.