Boost logo

Boost :

Subject: Re: [boost] [TypeIndex] Peer review period for library acceptance begins, ending Thurs 21st Nov
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2013-11-14 18:11:34


On 15 Nov 2013 at 10:51, Gavin Lambert wrote:

> Well, thus far when using type_info as an index into a collection I use
> only its type_info* value (as this is guaranteed by the standard to be
> unique per type but constant across multiple invocations of typeid on
> the same type of object), and name() is only used to print a human
> readable name (via MSVC) for diagnostic purposes (since the standard
> does NOT guarantee that the string value be unique, unlike the pointer,
> it's not really suitable for use as a key -- although granted most of
> the time you can get away with it). It's also faster. :)

Unfortunately typeid() does NOT necessarily return the same type_info
instance for some type if done across DLL or shared object
boundaries. This is because the compiler generates static type_info
instances only for those types where typeid() is used (with weak or
selectany linkage), and the linker links them up as if they were any
ordinary structure instance. That means a copy per DLL/SO.

The workaround is to use the mangled type specification, and to do a
string comparison to match them. That works very well, so long as you
are using the same compiler. In my own code I have even dumped the
mangled form to disc as an easy type identifying string id for an
on-disc type database (expect more of this coming for my C++ Now 2014
presentation if it is accepted!).

Due to these interop problems Antony's TypeIndex does string
comparisons as well. It's the only reliable way I believe.

> I think that at a minimum if RTTI is enabled then
> boost::type_info::name() must return exactly what std::type_info::name()
> would, on that platform. (This is still "least cost" since it'd just be
> passing the return value through without modification.)

Me personally I'd prefer name() to always return the mangled name on
every platform so it's portable and consistent. Unless one is using a
quirks type shim not called boost::type_info.

Remember that boost::type_info is not intended to be an exact
replacement for std::type_info. It is expected that Boost code using
std::type_info will need "porting" to boost::type_info. Antony has
provided all the necessary patches required for many Boost libraries.

> It should be free to add additional methods (such as raw_name or
> short_name or long_name or whatever) that can do whatever, including
> memory allocation and returning temporary values, but as long as
> drop-in-replacement is a goal it can't be allowed to change the
> behaviour of name() itself.

Again, it's not intended to be a perfect drop in. I do see Steven's
point about it accidentally becoming treated by the compiler as a
perfect drop in due to type slicing. How serious that is is something
I'll need to consider.

> When RTTI is disabled, of course, it has more freedom in the actual
> returned value because the standard name() doesn't exist. But it still
> must be able to return a const char* that has static lifetime, because
> people are expecting that from the RTTI-enabled case. (In particular,
> it must be legal to call name() on a temporary and use the returned
> value as a bare const char* at any later point in the code, even once
> the temporary is out of scope.)

On non-MSVC compilers, merely the attempt to access or create a
type_info would generally cause a compiler error if RTTI is disabled.
I therefore think that in this use case boost::type_info can merrily
do whatever it feels like, with any API definition it feels like
including returning std::string from name(). After all, the code
didn't compile at all before, so no backwards compatibility is needed
here - if it compiles at all and no semantics are broken, who cares?

On MSVC, typeid() works just fine as does type_info if RTTI is
disabled. It's just that typeid() can no longer cope with
polymorphism and the compiler warns if you try to use typeid with a
polymorphic type. Here things are tougher if and only if there is
Boost code written to work on MSVC with RTTI off. I don't believe
there is any such code in Boost, and therefore this is also a
non-issue.

> If the library is intended to be an alternative implementation that is
> *not* a drop-in replacement, then some of these strictures could be
> relaxed a bit (and it shouldn't inherit from std::type_info any more).

My overwhelming concern with boost::type_info is whether the present
implementation will cause surprises. Antony has already done a lot of
work to remove a lot of surprises by generating warnings or static
assertion failures. I need to ponder more deeply the concern about
undefined behaviour during a type slicing cast vs having it act as a
proxy to a const std::type_info & supplied via a constructor. It'll
take me a few days to ponder this I think. The latter is not
undefined behaviour, but do you actually gain anything in practice?

Niall

-- 
Currently unemployed and looking for work.
Work Portfolio: http://careers.stackoverflow.com/nialldouglas/



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