$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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/