Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class identity without RTTI

Tags:

c++

identity

rtti

I've found a simple solution somewhere on the internet to an identity class without built-in C++ RTTI.

template <typename T>
class Identity {
public:
    static int64_t id()
    {
        static int64_t dummy;
        return reinterpret_cast<int64_t>(&dummy);
    }
};

When we need some class ID, we just use:

Identity<OurClass>::id();

I'm wondering, are there any collisions? Can it return the same ID for the different classes, or the different ID for the same classes? I have tried this code with g++ with different optimization values, everything seems ok.

like image 829
pproger Avatar asked Jun 17 '12 11:06

pproger


People also ask

What is runtime type identification (RTTI) in C++?

What Is Runtime Type Identification (RTTI) in C++? RTTI stands for Runtime type identification. It is a mechanism to find the type of an object dynamically from an available pointer or reference to the base type. This is particularly useful in a situation where we do not want to rely on the type identification by the virtual function mechanism.

What is the purpose of RTTI in C++?

This feature was added to C++ with the introduction to exception handling because knowing the runtime type was vital in dealing with exceptions. The RTTI provides an explicit way to identify the runtime type separately from what is possible with the virtual function mechanism.

When to use RTTI instead of polymorphism?

The idea is that RTTI should be used only when the polymorphism in code is unable to serve the purpose. The use of RTTI may leverages efficiency at times, but defeats the purpose of polymorphic niceties. This may create a problem in code maintenance in the long run.


1 Answers

First off: there is such an integral type that is made specifically to contain pointers:

  • intptr_t
  • and in C++11 uintptr_t

Second, even though in practice on gcc they are equal, the size of a pointer to an object and the size of a function pointer (or pointer to member) might well be different. Therefore it would be better using a specific object rather than the method itself (for Standard conformance).

Third, it only gives you identity, while RTTI is much richer, as it knows about all the subclasses a given object can be cast to, and even allows cross-casts or casts across virtual inheritance.

Still, the corrected version can be useful I guess:

struct Foo {
    static intptr_t Id() {
        static boost::none_t const Dummy = {};
        return reinterpret_cast<intptr_t>(&Dummy);
    }
};

And in hierarchies, having a virtual function returning that ID.

For completeness, I'll mention that Clang and LLVM have their own way of dealing with object identification without RTTI. You may want to read about their way of implementing isa, cast and dyn_cast here.

like image 111
Matthieu M. Avatar answered Sep 28 '22 01:09

Matthieu M.