0

Given:

Example.h

struct Base {
    virtual ~Def() = default;

    virtual void accept(struct DerivedVisitor* v) = 0;
};

struct Derived : Base {
    int num;
    void accept(struct DerivedVisitor* v) override;
};

struct DerivedVisitor {
    virtual void visit(Derived* d) = 0;
};

Example.cpp

#include "Example.h"

void Derived::accept(struct DerivedVisitor* v) {
    v->visit(this);
}

Say that I wanted to create an instance of Derived from "scratch". As it contains a virtual function, from Base, how would i get a hold of the address to its virtual function table so that i could do something like this:

main.cpp

#include <iostream>
#include <memory>
#include "Example.h"

struct Visitor : DerivedVisitor {
    void visit(Derived* d) override {
        std::cout << d->num << std::endl;
    }
};

int main() {
    int num = 5;
    
    // Create Derived instance from scratch
    auto der = malloc(sizeof(Derived));
    auto derBytes = static_cast<char*>(der);
    new (derBytes) void*(/*HERE I NEED POINTER TO Derived VFT*/); // <------------- How?
    new (derBytes + sizeof(Base)) int(num);

    // Just to see that it works:
    Base* base = reinterpret_cast<Derived*>(der);
    Visitor visitor{};
    base->accept(&visitor);

    free(der);
    return 0;
}

Is this compiler specific? If so, I am using MinGW if anyone is familiar with it.

Django
  • 57
  • 6
  • 4
    This seems like an XY problem. Virtual function tables are an implementation detail and need not even exist on a C++ implementation. – nanofarad Jul 21 '20 at 00:40
  • There is no good reason to do this. What are you REALLY trying to accomplish? – Remy Lebeau Jul 21 '20 at 01:08
  • Im trying to build a LR(1) parser that can parse any LR(1) grammar given its descriptions. The result of the parse should then be stored in a AST, which consists of classes for the different rules in the grammar. Since the parser is general, it can not know the specific classes that make up the AST, as these are generated depending on the grammar, and therefore needs to construct the AST from a memory layout description. Once the memory has been filled out correctly, a reinterpret_cast on the top node of the AST can be done by the caller of the parser. This is the idea anyhow. – Django Jul 21 '20 at 01:46
  • I think I found a workaround however. The caller does know the specific class' of the AST and can therefore send as arguments to the parser all the pointers to the class' vtables. Im using virtual functions in the AST in order to navigate it with the visitor pattern in a type-checker/interpreter/compiler. If there are ideas of how this could be done cleaner, I would appreciate the help. :) @RemyLebeau – Django Jul 21 '20 at 01:50
  • Where do you define `Def`? – curiousguy Sep 25 '20 at 11:00

1 Answers1

1

Is this compiler specific?

Yes, this is compiler specific.

There is no such thing as a "virtual function table" in the C++ language. Such table is an implementation detail.

Given that such table doesn't exist in the language, there is also no way to get a pointer to the table in standard C++. Assuming your compiler has such thing as a virtual table (which is a reasonable assumption), then it may be possible that your compiler documents a way to access it. I doubt that however. You may have to do that in assembly language.

eerorika
  • 232,697
  • 12
  • 197
  • 326