I would like to test C++ functions in a piece of code by swapping them one by one for ones that are known to work in a working context, where the swapping is done using the linker. (I use C++ with GCC under linux.) Unfortunately I do not know enough about how to drive the linker to know how to do this or even if it is possible.
For me, the main reason is to test students' code against a teacher's model solution, though I can imagine plenty of other cases where such methods may be of interest. Note that the students' source code is available and can be compiled in any way I like, but this source cannot be edited. However, the teacher's code can be modified as needed.
There follows a simple example that shows the idea.
Here is, the teacher's code, in which the functions can call each other in ways similar to that shown. All functions here are assumed to meet their specifications exactly.
#include <iostream>
using namespace std;
// model teacher program : main calls g which calls f
int f(int x) {
cout << "in teacher-f(" << x << ")" << endl;
return 46;
}
int g(int x) {
cout << "in teacher-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 91;
}
int main() {
cout << "in teacher-main()" << endl;
int x = 2;
int y = g(x);
cout << "g(" << x << ") returned " << y << endl;
}
A typical student's code, attempting to meet the same specifications, to be tested. In my case a "main", several #includes, and "using namespace std;" would be expected.
#include <iostream>
using namespace std;
// model student program : main calls g which calls f
int f(int x) {
cout << "in student-f(" << x << ")" << endl;
return 27;
}
int g(int x) {
cout << "in student-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 82;
}
int main() {
cout << "in student-main()" << endl;
int x = 4;
int y = g(x);
cout << "g(" << x << ") returned " << y << endl;
return 0;
}
I want to swap each of the teacher's functions one by one to test each student function individually.
Here is one attempt, in this case testing the student's g()
g++ -c student.cpp
# (this makes student.o)
# strip f() and main() from student.o:
strip -N main -N _Z1fi student.o
# similarly for teacher, but stripping g
g++ -c teacher.cpp
strip -N _Z1gi teacher.o
g++ -o final teacher.o student.o
./final
and the result I would expect is
in teacher-main()
in student-g(2)
in teacher-f(2)
f(2) returned 46
g(4) returned 82
unfortunately, I get:
strip: not stripping symbol `_Z1fi' because it is named in a relocation
I have tried doing something similar with .so libraries instead. The error message to strip disappears, but unfortunately this time the teacher main calls the teacher g that I had tried to remove.
g++ -shared -fPIC -o student.so student.cpp
g++ -shared -fPIC -o teacher.so teacher.cpp
strip -N main -N _Z1fi student.so
strip -N _Z1gi teacher.so
g++ -o final teacher.so student.so
./final
giving
in teacher-main()
in teacher-g(2)
in teacher-f(2)
f(2) returned 46
g(2) returned 91
Any suggestions? Is this even possible? If not, is there any way round to do the same thing? As said I cannot edit student.cpp, but I could #include it from other source code.
Thanks Richard