Wenn ich selbst einen einfachen Code mit einem Feature des C ++ 11-Standards kompiliere (die Funktion std::stod
), schlägt GCC 4.9.1 mit dem folgenden Fehler fehl:
Was?
Der Befehl, den ich verwende, ist g++ -std=c++11 example.cpp
.
Dies ist der Testcode (der auf anderen Systemen gut übersetzt wird):
%Vor%Ich verwende eine Version von GCC 4.9.1 Ich habe mich selbst auf zwei verschiedenen Clustern mit CentOS 6.5 kompiliert (ich benutze das Modulsystem für Sachen in meinem Home-Verzeichnis, da ich kein Administrator bin).
Ich nenne sie Cluster 1 und Cluster 2 : Cluster 1 ist der Ort, an dem der Fehler auftritt.
Die GCCs wurden auf die gleiche Art und Weise kompiliert und mit identischen Moduldateien geladen (abgesehen von einem kleinen Unterschied im Basispfad). Die Installationen sind, soweit ich das leicht überprüfen kann, identisch (die gleichen Include-Dateien existieren auf beiden Clustern und haben den gleichen Inhalt).
Die Ausgabe von g++ -v
ist in beiden Clustern identisch (abgesehen vom Installationspfad):
g++ -v
unter Verwendung des System-GCC gibt die gleiche Ausgabe auf beiden Clustern, außer auf Cluster 1 sagt es ist gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
und auf Cluster 2 sagt gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
Ich versuche zu debuggen mit g++ -std=c++11 -save-temps -MD example.cpp
für mehr Informationen ... das gibt einige Hinweise, aber ich weiß nicht, wo ich von hier aus gehen soll.
In den Zwischen-Dateien ( .ii
) in Cluster 1 fehlen z. B. einige Zeilen (Auszug aus diff
in den .ii
-Dateien):
Wie ich es interpretiere, versucht GCC auf beiden Clustern, Dateien wie cwchar
einzubeziehen, aber auf Cluster 1 gibt es leere Zeilen anstelle von Dingen, die definiert werden. Auf dem Cluster 2 befindet sich die Funktion stod
in der Zwischendatei, nicht jedoch im Cluster 1 .
Könnte es sich um einen Präprozessorfehler handeln?
Betrachtet man nun die Dateien .d
(Abhängigkeit), sehe ich auch einen konkreten Unterschied. Auf dem Cluster 2 sind einige Dateien aufgeführt, die nicht im Cluster 1 aufgeführt sind. Hier ist die Liste (Ich habe den Inhalt der .d
-Dateien verarbeitet, um die verschiedenen Basispfade zu berücksichtigen; //
steht für den Installationspfad):
Ich war neugierig, ob cpp
an allen falschen Stellen nach Includes suchte, aber das scheint legit ( cpp -v
):
Dies war ein sehr frustrierendes paar Stunden, um die Ursache des Problems zu finden. Ich könnte natürlich etwas wie atof(myString.c_str())
anstelle von std::stod
verwenden, aber ich frage mich, ob es ein zugrunde liegendes Problem gibt, das zukünftige Projekte mit anderen Bits von C ++ 11 verschmutzen wird.
Weitere Hinweise oder Einblicke wären sehr willkommen.
Sie haben bereits alle notwendigen Schritte unternommen, um die Ursache zu ermitteln. Sie kennen die Antwort bereits: Sie haben klare Unterschiede zwischen der Funktionsweise von benutzerdefinierten gcc-Installationen auf Ihrem "Cluster 1" und "Cluster 2", einem nicht funktionierenden und einem funktionierenden Build, veröffentlicht.
Es ist also offensichtlich etwas Unterschied zwischen diesen beiden gcc-Installationen; Wenn man einen Code kompiliert, verbindet und ausführt, dockt der andere an genau demselben Code an. Leider ist es schwer festzustellen, wo die Dinge aus den Fugen geraten. Ich habe gcc schon mal selbst gebaut, vorher kann ich sagen, dass gcc ein höllisch schwieriges und sehr unbeständiges Paket zu installieren ist. Nachdem ich zum Beispiel einige Tage lang einen mysteriösen Fehler bei der Verlinkung von C ++ - Code gejagt hatte, habe ich ihn nach gcc gejagt, um die falsche Version von binutils im gcss configure-Skript aufzuheben und intern ein obskures Feature zu deaktivieren, das sich schließlich als selbst manifestierte ein Link-Fehler nicht von gcc, sondern von Sachen, die mit gcc gebaut wurden. gcc selbst wurde gebaut und installiert, mit keiner Beschwerde, aber es war kaputt.
Also finde ich es völlig überraschend und absolut plausibel, dass gcc selbst ohne ein offensichtliches Problem gebaut und installiert wurde, aber es ist kaputt und wird auf diese Weise an einem gültigen Code ersticken.
Ich nehme an, dass Ihr kaputtes gcc-Build einen defekten Standard-Include-Pfad verwendet - es sucht nach Kopfzeilen in /usr/include
statt nach Ihrem eigenen benutzerdefinierten Installationsverzeichnis. Das ist die wahrscheinlichste Antwort, aber es könnte wirklich alles sein.
Nun, Sie haben offensichtlich (wie Sie selbst geschrieben haben) zwei verschiedene Versoins von gcc (einmal 4.4.7-3 und die anderen 4.4.7-4), und es scheint, dass sie (wenn auch leicht) Unterschiede haben Kompilieren des Codes.
Wie ich irgendwo gelesen habe, ist der C ++ 11-Standard noch nicht vollständig in allen Compilern enthalten, daher scheint dies der Grund für den einen Cluster zu sein. Der andere hat (wahrscheinlich wissen Sie, warum) eine Version, in der mehr von dem neuen Standard enthalten ist, und da Sie genau diese Funktion verwenden möchten, würde ich empfehlen, diese Version auch auf dem anderen Cluster zu installieren.