Skip to content

Instantly share code, notes, and snippets.

@wilkie
Created July 19, 2011 07:27
Show Gist options
  • Save wilkie/1091578 to your computer and use it in GitHub Desktop.
Save wilkie/1091578 to your computer and use it in GitHub Desktop.
This shows the fallacy of a virtual function. (in C++, but same logic applies to D or C#)
#include <stdio.h>
// This is the implementation of the class
// The functions go in order a(), b(), then c()
// The constructor or compiler will build a vtable as [&a, &b, &c]
class A {
public:
A();
virtual void a() {
printf("Executing a()\n");
}
virtual void b() {
printf("Executing b()\n");
}
virtual void c() {
printf("Executing c()\n");
}
};
A::A() {
}
// This is the interface of the class
// The functions go in order c(), b(), then a()
// The virtual table is assumed to be built as an array of function pointers: [&c, &b, &a]
// It doesn't provide ANY code to the class, so it actually assumes it will be linked to the code
// that will build this table in this particular order.
class A {
public:
A();
virtual void c();
virtual void b();
virtual void a();
};
// The only thing foo.cpp is aware of is the class as defined by A.h
#include "A.h"
// Remember the vtable it assumes will be [&c, &b, &a]
// Because of this, the call to a() will be assumed to be entry 2 of the table.
// However, A.cpp builds the table in reverse order, so it will execute c() instead.
#include <stdio.h>
int main() {
A* a = new A();
printf("Running a->a()\n");
a->a();
return 0;
}
// If only it would order the functions in a sane manner beforehand (alphabetical), it would
// not be a concern. Or if it used relocations/symbols to push responsibility to the linker.
foo: A.cpp foo.cpp
g++ -c A.cpp
g++ -c foo.cpp
g++ -o foo foo.o A.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment