C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Extend std::type_info with more information

From: Thiago Macieira <thiago_at_[hidden]>
Date: Sun, 14 Apr 2024 23:49:52 -0700
On Sunday 14 April 2024 23:37:40 GMT-7 Frederick Virchanza Gotham via Std-
Proposals wrote:
> But even for types that aren't trivially-copyable, we could store the
> address of the copy-constructor inside the extended_type_info (which
> is actually what std::any does in order to make it copyable):
>
> class std::extended_type_info {
> void (*address_of_copy_constructor)(void*,void const*);
> uint64_t traits;
> size_t size_of, align_of;
> };
>
> void CopyConstruct( void *const dst, void const *const src,
> extended_type_info const &eti )
> {
> eti.address_of_copy_constructor(dst,src);
> }
>
> Of course while we're at it, we could store the address of the
> destructor in there as well. We could probably make the
> extended_type_info a hundred bytes long . . . maybe even a kilobyte.
> I'm just floating this idea here to see what people are interested in
> having inside an 'extended_type_info', because at the moment
> 'type_info' is very sparse.

You keep putting the cart ahead of the oxen...

Start by finding use-cases first. Then you find the traits that need to be stored
by pointer or by a flag. Not the other way around.

Hint: look at QMetaType and how/where it is used. Everything you've described
here is in there.

> I think a good place to start would be to have a 64-Bit integer with
> all the boolean type_traits.

No. It should be a handful of bits that make sense to be used. The vast
majority of type traits aren't useful in a type-erased context. So, again,
start with the uses and problems that need solving, not the solutions.

> > Extending runtime type information is an ABI break and potentially
> > wasteful for programs with lots of generated types.
>
> Two ways to prevent ABI breaking when extending type_info:
>
> (1) Have a totally separate type and a totally separate operator

Yep, that's called QMetaType. Been there, done that, proven that it works,
except in the corner-cases of DLL-crossing where it doesn't.

> (2) Derive a type from std::type_info, and use dynamic_cast to find it
>
> class std::extended_type_info : public std::type_info {
> uint64_t traits; size_t size_of, align_of; };
> int main(void)
> {
> std::extended_type_info *eti =
> dynamic_cast<extended_type_info const*>( &typeid(int) );
> if ( nullptr != eti ) DoSomething( *eti );
> }

One important difference is whether this is opt-in or opt-out.

Remember the C++ rule of "don't pay for what you don't need". If you try to
extend the amount of information that needs to be generated for each and every
polymorphic class by tens of bytes (let alone hundreds), you're going to face
opposition to making it default.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Principal Engineer - Intel DCAI Cloud Engineering

Received on 2024-04-15 06:49:54