Boost logo

Boost :

From: Jody Hagins (jody-boost-011304_at_[hidden])
Date: 2005-02-23 17:42:27


As noted eariler, I have been working on moving the type_info/typeid
stuff into a more common place. I have been using the implementation in
boost/python/type_id.hpp as a reference, because that code seems to have
addressed many issues related to different compilers. However, some of
the workaround code prohibits standard confirming calls, so I wanted to
get some input here.

I am conflicted as to giving a summary or providing full details. I
will probably end up doing a bit of both...

The biggest problem is that on some older compilers, calls to the
typeid() operator incorrectly leave outer reference and cv-qualifiers
when returning type_info.

Some interesting code exists to workaround this problem, resulting in a
type_id() function. I have expanded this functionality to get most of
5.2.8 working. However, there are several pieces of 5.2.8 that are not
possible (at least to me), using a fix like this. I have tried using
macros, and some other tricks, but can not get full conformance to
5.2.8.

So, maybe I can get a little help. The "bad" compilers are currently
recognized by this incantation.

#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) \
    || (defined(BOOST_INTEL_CXX_VERSION) \
        && BOOST_INTEL_CXX_VERSION <= 700)

What versions of MSVC/Intel does this include? Is support for them
still necessary? If so, is it reasonable to leave in a type_id function
that does not conform to 5.2.8, letting the buyer beware?

Also, it is remotely possible that implemeting 5.2.8 fully is possible
with a workaround, but I have been unsuccessful using gcc. I basically
"force" the workaround to be used by adding defined(__GNUC__) so I can
test the workaround code.

The closest I can come is defining a macro...

#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) \
    || (defined(BOOST_INTEL_CXX_VERSION) \
        && BOOST_INTEL_CXX_VERSION <= 700)
# define BOOST_TYPEID(x) \
        // Some funky stuff
#else
# define BOOST_TYPEID(x) typeid(x)
#endif

but still under the "bad" compilers, some code does not compile, and
other code causes tests to fail. This leaves users with some leeway.
If you do not care about compiler bug workarounds, use typeid(). If you
do care, use the BOOST_TYPEID() macro. However, if you are using a
"bad" compiler, some things will either not compile, or will give the
wrong behavior.

FWIW, the current workaround only supports static types, and does not
support lvalue at all. I have added this, but it has some problems.

FWIW, the most difficult parts of 5.2.8 to get right with the workaround
are:

5.2.8.2: I am having problems stripping the qualifiers and still leaving
the most derived information

5.2.8.2: once the expression is evaluated, unless call directly to
typeid(), a segv happens instead of std::bad_typeid exception being
thrown.

5.2.8.3: The expression is not supposed to be evaluated (the expression
is only allowed to be evaluated if the expression results in a
polymorphic type or a pointer to a polymorphic type is dereferenced --
see 5.2.8.2).

I would gladly appreciate any questions/comments.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk