Created
July 19, 2011 07:27
-
-
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#)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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