Boost logo

Boost :

Subject: Re: [boost] Peer Review Report for proposed Boost.TypeIndex v2.1 Nov 12th – 21st 2013
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2013-11-25 20:41:49


On 25 Nov 2013 at 23:35, Andrey Semashev wrote:

> Yes, I understood you meant something like that (although your type_index
> derives from static_string which does contain a data member). But that
> type_index cannot be used as a key in std::map for instance, and therefore it
> is not the equivalent for std::type_index which I'm interested in.
>
> You could argue that you can use static_string in containers but what's the
> point of it if you can already use flyweight<string> or a string_ref with the
> same success. The point of type_index is not just strings but RTTI, which is
> in most cases more efficient than strings.

I am still struggling to understand the merit of your argument. All
type_info really is is a const char string of the mangled type (if
you leave out virtual inheritance, which BTW is simply a linked list
of pointers to more mangled type const char strings, so all a
dynamic_cast<> does is to iterate strcmp() up/down the chain until it
finds the right one). That's RTTI, no more, no less.

Both GCC and MSVC internally use strcmp() on those strings when
comparing type_info's, including for ordering for use in std::map<>.
hash_code() I would also be fairly sure is simply a hash of the
mangled type string. Therefore what I proposed is almost the same
thing as RTTI, and certainly IS the same thing for use as value types
inside containers. The only difference when RTTI is off is that the
strings become a bit longer to compare and store, and that's it.

> I'll remind you again that std::type_info::name() is not required to return a
> mangled name, and __func__ is not required either. On a perfectly compliant
> implementation your mangled_name() would fail and that is not acceptable, IMO.

Unless I misunderstood something, the previous complaints about
name() was that it MUST return EXACTLY what
std::type_info::name()/raw_name() does. If it can't return EXACTLY
what name()/raw_name() does, it must not be there at all.

As I have previously discussed more than once now, the use of
name()/raw_name() to retrieve the underlying mangled string is a very
commonly used idiom. Most type registries use it e.g. the one in
Boost.Python because it's the only way you can compare type_info's
for equivalence across DLLs. I can certainly see why it is so
important that it return the exact same string, and hence why I think
any name()/raw_name() not returning EXACTLY what std::type_info does
is unwise. My opinion here is to simply leave it out, and let user
code subclass their own derived class which implements whatever
name() they prefer.

> You can provide such a function as an optional extension, with the necessary
> macros to detect its availability in the client code, but putting it into the
> core interface of the library is a mistake.

If I understand what your argument has been so far, I would disagree
with you. I think you don't understand how type_info works under the
hood.

> > No one is suggesting one would use mangled_name() for anything
except
> > where you need to compare a boost::type_index<T> with a
> > std::type_info for equality. There you can compare the strings
> > returned by each for equality - if they are equal, they refer to
the
> > same type.
>
> No they don't. You can never test boost::type_index and std::type_info
> for equivalence by comparing their names.

You appear to think there can only ever be one const std::type_info&
instance per typeid(T) for some type T. You are very, very wrong, and
no compiler in recent years thinks so [1].

[1]: Many years ago GCC did assume different type_info instances must
always refer to different types. My patch adding -fvisibility support
to GCC 4.0 caused multiple type_info instances to be emitted for a
type (one per SO), and therefore type_info comparisons since GCC 4.5
now do string comparisons of their containing mangled type string
[2]. MSVC has always done a full string comparison to my knowledge.

[2]: You probably want proof of this, because plenty of people don't
believe me. Look at
http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a01071_sourc
e.html around line 47. It'll explain the __GXX_MERGED_TYPEINFO_NAMES
macro and it has the following sentence "We used to do inline pointer
comparison by default if weak symbols are available, but even with
weak symbols sometimes names are not merged when objects are loaded
with RTLD_LOCAL, so now we always use strcmp by default".

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