Register
Handmade Hero»Forums»Code»Virtual function's disadvantage and real-life examples
17 posts
Virtual function's disadvantage and real-life examples
1 month ago Edited by longtran2904 on July 2, 2021, 5:27 p.m. Reason: Initial post
I heard Casey said in one of his clip is that he hate virtual function because it's not serializable, can't change at runtime, can't tightly pack, etc. I don't really understand what did he mean when he said it's not serializable? And why do you need it to be? Also, some real-life examples for the need of changing at runtime, pack tightly, etc, and the way you achieve it will be helpful.
Mārtiņš Možeiko
2244 posts / 1 project
Virtual function's disadvantage and real-life examples
1 month ago
Not serializable means you cannot memcpy it to byte buffer for saving/restoring later, or for saving to file, or transmitting over network. Because those bytes will include pointer to function addresses that may be not valid when exe is run later / different computer. Technically you don't "need it", but it makes a lot of things simpler when you can simply memcpy structures around.
17 posts
Virtual function's disadvantage and real-life examples
1 month ago
Is it because the vtable is a compiler implementation detail and you can't access it? So if you try to memcpy it, does it still copy the virtual function pointer? If I make my own vtable then it still may not be valid when run later or on a different computer.
Mārtiņš Možeiko
2244 posts / 1 project
Virtual function's disadvantage and real-life examples
1 month ago
Yes, that is correct. Not only vtable pointer itself can change, but also all the methods it points to can change. So there's a lot of patching involved if you want to memcpy it.
17 posts
Virtual function's disadvantage and real-life examples
1 month ago
Another disadvantage that Casey pointed out is that you can't change it at runtime. I can't really think of any reason to do so. Do you have any real-life examples?
500 posts
Virtual function's disadvantage and real-life examples
4 weeks, 1 day ago
when you want to recycle an object's allocation but as a different subclass.

That is technically possible using placement new but requires that you give each subclass enough memory for the largest one. But there are zero checks on that in C++ so accidentally going out of bounds is far too easy.

17 posts
Virtual function's disadvantage and real-life examples
4 weeks, 1 day ago
There's something I still don't understand. When I make a virtual function, the compiler adds a function pointer to the vtable at the beginning of my struct. When I memcpy it, technically it still copies the function pointer, right? So why isn't it serializable? And why make my own vtable would solve it? Also does adding a virtual function increase my struct size?
Mārtiņš Možeiko
2244 posts / 1 project
Virtual function's disadvantage and real-life examples
4 weeks, 1 day ago Edited by Mārtiņš Možeiko on July 5, 2021, 8:59 p.m.
Because when you run your exe next time, OS loads it into different location - so all your pointers to functions (and global variables/data) are now invalid.

In simplest case if you have virtual function in your struct (or any of its base classes) then struct will have only one extra pointer at beginning. It will point to virtual table that has as many entries as there are virtual functions. So adding extra virtual function will increase count of this table/array, but not struct itself. It gets more complicated with multiple & virtual inheritance.
17 posts
Virtual function's disadvantage and real-life examples
4 weeks ago
But if I make my own vtable then it still not solve this. The next time I run the program, all the pointers will point to different locations.
Mārtiņš Možeiko
2244 posts / 1 project
Virtual function's disadvantage and real-life examples
4 weeks ago Edited by Mārtiņš Možeiko on July 6, 2021, 5:22 p.m.
That is the point of this - to not create vtables to allow memcpy'ing around. Usually alternative to virtual tables in C are discriminated unions. You have struct with enum type and union of all possible types. Then you switch based on type. This way you can memcpy it around because type is just an integer in memory:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
enum Type { Cat, Dog };
struct CatStuff { ... };
struct Dogtuff { ... };

struct Animal {
   Type type;
    union {
      CatStuff cat;
      DogStuff dog;
   };
};

Of course you don't need to do that for whole contents of struct. Sometimes just one "SomeType type" member is enough without any unions. Then you simply do switch on it at runtime to call appropriate function - this way resolving function call addresses will happen at runtime, in place where switch is and not stored inside struct.
This is most trivial way to do it. Other way is to design your structs to have everything you need ("fat structures"), or have array with variable amount of properties that you access individually.
17 posts
Virtual function's disadvantage and real-life examples
4 weeks ago
Ok, I understand it now. Thank you for answering!