Max Young
Max Young

Reputation: 1662

Is it possible to modify type definitions at runtime?

Is it possible to modify type definitions at runtime? For example if you were to define a class like this

class Test {
   public:
       int x;
       int y;
};

could I remove the x or y field from the class at runtime? Or could I add more fields to this like adding a z field?

EDIT: This question is strictly out of curiosity.

Upvotes: 2

Views: 349

Answers (3)

user1196549
user1196549

Reputation:

C++, by legacy from C, stores as little information as possible at run-time. For this reason, it does not support introspection and does not keep a run-time definition of the data types. On the opposite, the layout of structures is kept implicit, by having the correct offsets used in address computations. Thus the complete layout must be known at compile-time.

Upvotes: 1

Artyom K
Artyom K

Reputation: 64

No. It is definitely impossible.

For example, we are updating the field x in the structure Test and we must know the size at the compile time because of operations on machine code level performs on data offsets

class Test {
   public:
       int x;
       int y;
};


int main(){
    Test t;
    t.x = 10;
    return t.x - 1;
}

Expands to

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-8], 10
        mov     eax, DWORD PTR [rbp-8]
        sub     eax, 1
        pop     rbp
        ret

We are accessing the field x by direct writing the value into the address [rbp-8] (rbp holds the current frame pointer). We are subtracting 8 instead of adding because of the stack grows from the upper address to the lower.

But with C++ standard library and some masochistic tendencies you can write something like that (holding values in the variable 'values')

#include <any>
#include <iostream>
#include <map>
#include <string>

class Test {
   public:
       int x;
       int y;
};

int main(){
    std::unordered_map<std::string, std::any> values;
    values.insert({"pi", 3.14f});
    values.insert({"test", Test{1,1}});

    std::cout<< std::any_cast<float>(values["pi"])<<std::endl;
    std::cout<< std::any_cast<Test>(values["test"]).x<<std::endl;
}

Upvotes: 4

MSalters
MSalters

Reputation: 179799

No. You can do this at compile time, with some effort. C++ has templates. You can use a template argument to choose between different variants of Test, some with x and some with a z. But the template argument has to be a compile-time constant. You cannot get it from std::cin.

Upvotes: -1

Related Questions