2014-09-08 3 views
12

Ich fange gerade an, C++ zu unterrichten, komme von einigen anderen Sprachen. Ich wünschte, es gäbe eine Möglichkeit, die API, die von einer (Studenten-) Datei erstellt wurde, regelmäßig zu überprüfen.Gesundheit der Header

Angenommen, ein Student trägt diese Datei:

// this is stu.cpp 
#include <iostream> 
using namespace std; 
double x(int y) {return y+0.5;} 

Eigentlich nehme ich den Schüler fragte eine andere Funktion int x (int) zu definieren. Ich möchte in der Lage sein, dies zu überprüfen, indem Sie diesen Code ausführen:

// this is stu.h 
int x(int); 

// this is gra.cpp 
#include "stu.h" 
#include <iostream> 
using namespace std; 

int main() { 
    cout << x(0); // test their code 
} 

So versuche ich zu sehen, ob die Umsetzung des Studenten die erforderliche Schnittstelle angepasst, und Testen auf 0. Eingang Ich habe dies würde gehofft würde nicht kompilieren. Aber wenn ich

g++ -Wall -Wconversion *.cpp -o gra 
./gra 

Es kompiliert und läuft ohne Absturz, Ausgabe geben 0. Dies bleibt wahr, auch wenn ich die beiden Dateien separat und verknüpfen sie nach kompilieren.

Ich weiß, dass nm Rückgabetypen nicht auflistet. Ist das der gleiche Grund, warum wir zwei Dateien verknüpfen können, wenn die Rückgabewerte nicht übereinstimmen? Gibt es einen vernünftigen Weg, das zu testen? (Wie gibt es kompilierungszeit typeof Zusicherungen?)

Oder ist dies ein spezifischer Fehler wegen int und doppelt ineinander umwandelbar? Gibt es zusätzliche Compiler-Optionen, die dies erfassen könnten?

+3

Sie erhalten einen Fehler, wenn 'stu.cpp'' stu.h' enthält. –

+2

Yup, sollten Sie mit '-Wall -Werror -Wextra 'kompilieren, und geben Sie den Studenten die Header-Datei zu implementieren (was beinhaltet' # include'-ing). –

+0

Sie könnten versuchen mit 'g ++ -flto -Wall -Wconversion * .cpp -o gra' –

Antwort

8

Anstatt den Code des Studenten separat zu kompilieren, fügen Sie ihn einfach direkt in Ihr Testerprogramm ein.

int x(int); 
#include <stu.cpp> 

Dann sollten Sie einen schönen Fehler wie diese:

a.cpp:2:8: error: functions that differ only in their return type cannot be overloaded 

Dies ist zwar nicht die „normale“ Art und Weise ist ein Student Code zu kompilieren, garantiert es, dass der Code überprüft werden kann.


Alternativ können Sie einen Compiler-Befehlszeilenoption wie -include (GCC, Clang) den Compiler zu zwingen, eine Header-Datei mit dem gewünschten API zu enthalten, wenn die C++ Datei Schüler kompilieren. Als Beispiel:

api.h

int x(int); 

mit g++ stu.cpp -include api.h kompilieren, und der entsprechende Fehler wird erhöht werden.

+1

Es kann jedoch zu falsch positiven Ergebnissen führen, z. B. zur Neudefinition von Symbolen. –

+0

@OliCharlesworth: Warum? Die erste Lösung enthält "stu.cpp", so dass 'stu.cpp' nicht unabhängig kompiliert werden würde. Die zweite Lösung fügt nur einen Header der Wahl des Graders ein, der nur Funktionsprototypen enthalten sollte. Ich sehe nicht, wo Symbolredefinitionsfehler auftreten würden? – nneonneo

+0

Es gab eine andere Antwort, jetzt gelöscht, mit Funktionszeigern, die ziemlich elegant war, vor allem, weil es auch leicht machen würde, zu überprüfen, wenn ein Schüler die Methode nicht definiert hat. Gibt es bei diesem Ansatz eine Möglichkeit, einen Fehler zu melden, wenn die Methode nie definiert wurde? Ich bin besorgt, dass "nur versuchen, es aufzurufen" wird nicht immer funktionieren, da C++ automatisch viele Arten hinter den Kulissen konvertieren wird. – daveagp

1

Sie können folgendes tun:

// this is gra.cpp 
#include "stu.h" 
#include "stu.cpp" 
#include <iostream> 
using namespace std; 

int main() { 
    cout << x(0); // test their code 
} 

Und nur gra.cpp natürlich kompilieren.

Verwandte Themen