Keine Ausgabe...
-
In der LinearAlgebra.cpp steht folgender Code:
int main(int argc, const char* argv[]) try { cout << "ok" << endl; return 0; }Es kommt ganz normal die Ausgabe "ok".
Jetzt ergänze ich die Funktion
extern "C" SEXP rcpp_test() { Rcpp::NumericVector x(5); for (int i = 0; i < x.size(); i++) x[i] = i*i*i; return x; }Die main() lasse ich aber unangetastet. Plötzlich kommt einfach keine Ausgabe mehr. Dieses Verhalten kann ich mir irgendwie nicht erklären
Ich hab schon ein wenig experimentiert. Es reicht aus, wenn man eine Funktion
extern "C" void voidTest() { Rcpp::NumericVector x(5); }vor der main() stehen hat. Was kann so böse am NumericVector sein, dass plötzlich main() keine Ausgabe mehr ausgibt, obwohl voidTest() oder rcpp_test() nicht aufgerufen wird?
Was hinter dem NumericVector steckt, weiß ich nicht genau, da es sich um eine Bibliotheks-typedef handelt.
-
Irgendetwas anderes geht vor, das du uns verheimlichst oder was du selber gar nicht wahr nimmst. Du wirst vermutlich mindestens noch irgendeine Bibliothek dazu linken. Diese enthalt eventuell Objekte statischer Lebenszeit die noch vor der main initialisiert werden und eventuell mit einem nicht sichtbaren Fehler aussteigen. Oder ein Scherzkeks war an dem Code, der cout mittels Makro irgendwie umbiegt. Oder, oder, oder…
Eine gute Idee wäre, einfach mal mit einem Debugger schrittweise durch das Programm zu gehen.
-
Wenn ich den Debugger bei Eclipse starte, dann hält er normalerweise beim Betreten der main() an, sodass ich dann schrittweise debuggen kann. Wenn ich die oben stehende rcpp_test() hinzufüge, wird der Debugger direkt beendet. Exit value ist allerdings 0 statt einer (zufälligen?) negativen Zahl beim normalen Ausführen.
An cout liegt es nicht: Die main() wird gar nicht erst betreten.
-
Eine Möglichkeit wären dann statische Konstruktoren die vor der main ablaufen. Möglicherweise das berühmte static initialization order fiasco. Oder inkompatibel übersetzte Bibliotheken (z.B. kann es komische Effekte geben, wenn eine Bibliothek mit -pthread übersetzt wird, andere nicht). Oder ein "normaler" Fehler in diesen Konstruktoren (das genannte Fiasco ist natürlich auch ein Fehler).
Ist ein bisschen schwierig, so etwas zu finden, da du erst einmal rausfinden musst, welcher Code überhaupt ausgeführt wird, damit du Haltepunkte mit dem Debugger setzen kannst. Ein guter Einstiegspunkt könnte die Funktion _start sein, aber wie das genau heißt ist abhängig von deinem System.
-
Du bist aber schon sicher, dass das Programm übersetzt und gebunden wird, oder?
Wenn dir die Frage blöd vorkommt: du wärst nicht der erste hier, der das übersieht
-
manni66 schrieb:
Du bist aber schon sicher, dass das Programm übersetzt und gebunden wird, oder?
Ja.
SeppJ schrieb:
Eine Möglichkeit wären dann statische Konstruktoren die vor der main ablaufen. Möglicherweise das berühmte static initialization order fiasco. Oder inkompatibel übersetzte Bibliotheken (z.B. kann es komische Effekte geben, wenn eine Bibliothek mit -pthread übersetzt wird, andere nicht). Oder ein "normaler" Fehler in diesen Konstruktoren (das genannte Fiasco ist natürlich auch ein Fehler).
Aber wie kann es sein, dass mehr Code ausgeführt wird, wenn ich einfach eine Zeile zu einer Funktion hinzufüge, die nicht aufgerufen wird?
SeppJ schrieb:
Ist ein bisschen schwierig, so etwas zu finden, da du erst einmal rausfinden musst, welcher Code überhaupt ausgeführt wird, damit du Haltepunkte mit dem Debugger setzen kannst. Ein guter Einstiegspunkt könnte die Funktion _start sein, aber wie das genau heißt ist abhängig von deinem System.
Ich benutze Windows 7 und als Compiler MinGW (4.7). Kannst du mir sagen, wonach ich suchen muss?
Edit:
Ich hab einen Fehler gefunden:
Beim Ausführen fehlen Bibliotheken (*.dll), auf die zugegriffen werden müsste. Eclipse hat mir das Windows-Fenster mit der Fehler-Meldung aber gar nicht angezeigt. Als ich dann das Programm in der Konsole gestartet, kam das Fehler-Fenster...Ich hab jetzt die benötigten dll-Dateien in den gleichen Ordner gepackt, wie die exe. Gibt es da eine elegantere Möglichkeit?
-
Ich hab jetzt die benötigten dll-Dateien in den gleichen Ordner gepackt, wie die exe. Gibt es da eine elegantere Möglichkeit?
... als die DLL's immer mitzuschleppen? Statisch Linken, die PATH-Variable von Windows auf den gewünschten Pfad umändern oder die dll's nach windows\\system32 kopieren.
-
Wie geht das statische Linken?
Bisher linke ich durch:
g++ -LC:\Program Files\R-2.15.1\bin\i386 -lR -o TestProject2 src\Main.oWenn ich ein -static hinzufüge, kommt als Fehler:
c:/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../../mingw32/bin/ld.exe: cannot find -lR
-
statisches Linken funktioneirt natürlich nur mit statischen bibliotheken (libR.a), nicht mit dynamischen (libR.so)