Home > Software engineering >  How to check if a c typeid(T) call is compile time or runtime determined?
How to check if a c typeid(T) call is compile time or runtime determined?

Time:08-17

C keyword typeid has a magic: it know when to use compile-time type info and when to use runtime type info:

#include <iostream>
#include <typeinfo>
using namespace std;
struct Interface      { virtual void f() = 0;               };
struct S1 : Interface {         void f() { cout << "S1\n"; }};
struct S3 : S1        {         void f() { cout << "S3\n"; }};
int main() {
    S1 s1;
    cout << typeid(s1).name() << endl;
    S1* ps = new S3;
    cout << typeid(ps).name() << endl;
    cout << typeid(*ps).name() << endl;
    delete ps;
    return 0;
}

The program prints:

struct S1
struct S1 * __ptr64
struct S3

My question: does gcc/clang compiler has any compiler macro, or type_traits : that exposes typeid magic and tells us whether typeid(*ps) is compile-time determined or runtime-determined?

CodePudding user response:

Check this out:

template<typename T>
constexpr auto my_typeId(const T& value) {
    auto compileTimeChecked{ true };
    const auto& typeId = typeid(compileTimeChecked = false, value);
    return std::make_pair(compileTimeChecked, &typeId);
}

The first argument of the pair has true if typeid is resolved at compile time. false otherwise. The second member points to the resolved information const std::type_info *


The trick here is that typeid semantic changes depending on the argument it takes. If argument is an instance of a polymorphic class, then typeid actually evaluates the expression in runtime, and the side effect of compileTimeChecked = false comes into play. Otherwise typeid does not evaluate the expression (thus, compileTimeChecked = false never happens), but just takes the static type of value resolved at compile-time.

  • Related