Boost logo

Boost :

Subject: Re: [boost] Peer Review Report for proposed Boost.TypeIndex v2.1 Nov 12th – 21st 2013
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-11-25 22:28:20


On Monday 25 November 2013 20:41:49 Niall Douglas wrote:
> 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.

That's your assumption of its implementation. And it is one way to implement
it, indeed, but not the only one. My point is that type_infos are equivalent
only if type_info::operator== returns true and not necessarily when
strcmp(type_info::name(), type_info::name()) returns 0. The standard doesn't
give you that guarantee.

> Both GCC and MSVC internally use strcmp() on those strings when
> comparing type_info's, including for ordering for use in std::map<>.

GCC uses simple pointer comparison on platforms with appropriate linker
support. That doesn't include Windows though.

> hash_code() I would also be fairly sure is simply a hash of the
> mangled type string.

Again, that's just one possible implementation. Hashing just the address is
also possible, for example.

> 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.

Your solution has worse performance on some platforms and it also has the
potential to be incorrect, if names are not unique.

> > 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.

I assume, you mean when the native RTTI is disabled? That case is not normal,
because the standard describes the language with RTTI, so you're free to
provide the best possible alternative. But first think again alternative to
what exactly. The standard only says that type_info::name() returns some
string describing the type name. Anything that fits this description would be
a suitable replacement.

> 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.

The code that uses this concept is not portable and should not be advertised
in Boost, IMO.

> 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".

>From what I can see by the link you provided, type names can be compared
either by addresses or by strcmp, depending on the configuration (the
__GXX_MERGED_TYPEINFO_NAMES macro value). That only proves my point: don't
assume anything about the implementation, rely on the standard only.


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