Ich kompiliere meinen Quellcode auf zwei verschiedenen Maschinen, die verschiedene Versionen von gcc verwenden.
cflags c89
%Vor%Eins ist redhat-4
%Vor%Und eins ist Fedora 18
%Vor%Mein Fedora 18 kompiliert fehlerfrei. Auf der redhat 4 Maschine bekomme ich jedoch einige Fehler.
%Vor%Ich denke, der Fehler ist nur ein zirkuläres Problem. Aber mit der gleichen Code-Basis würde das Kompilieren auf 2 verschiedenen Maschinen wirklich einen Unterschied machen, wenn man 2 verschiedene Versionen von gcc verwendet?
Ich dachte, die Verwendung einer neueren Version eines Compilers würde mehr Fehler erzeugen, da der neuere Compiler strenger sein könnte.
Dies ist keine Frage, um den Fehler zu lösen, sondern eine allgemeine Frage zu Compilern.
Gibt es Flags, die ich einstellen kann, um dies in Zukunft zu vermeiden? Vielleicht, wenn das kompilieren auf dieser Version von gcc dies tun, wenn die Versionen nicht kompatibel sind?
Das ist ein Duplikat von: Warum" Redefinition of typedef "Fehler mit GCC 4.3, aber nicht GCC 4.6?
Die Antwort ist, dass gcc geändert wurde, um diese Prüfung zu modifizieren.
Manchmal werden Warnhinweise für das Verhalten, die in der Sprache definiert sind, aber als schlechte Praxis angesehen werden, als zu streng angesehen, da bestimmte nützliche und / oder harmlose Anwendungsfälle in der Warnung enthalten sind. Compiler-Entwickler versuchen dann, das Gegenteil zu beheben, dh die Anzahl der Warnungen zu reduzieren. In diesem Fall hat die Änderung die Warnung nur dann angezeigt, wenn die zweite Definition den Typdef in einen anderen, aber kompatiblen Typ geändert hat.
Ein anderes aktuelles Beispiel ist -Wshadow in gcc 4.8 gerade angekündigt. In der Release Note heißt es, dass -Wshadow nicht mehr warnt, wenn ein Funktionsname von einem anderen beschattet wird.
Siehe: Ссылка
Bearbeiten: Wie Sie das vermeiden können: Löschen Sie entweder eine der Definitionen oder verschieben Sie sie in eine separate Include-Datei und löschen Sie beide anderen Definitionen.
Es hängt davon ab, welche Header vom Quellcode enthalten sind. Wenn Sie eine Verknüpfung mit externen Bibliotheken herstellen, ist Ihr Quellcode möglicherweise nicht mit der Version einer auf dem älteren System installierten Bibliothek kompatibel.
Wenn der Quellcode keine externen Bibliothekskopfzeilen enthält (mit Ausnahme der C-Bibliothek), müssen möglicherweise Präprozessordirektiven geändert werden.
BEARBEITEN:
Nach einer Google Suche scheint channel_t
aus einer Kernel-Kopfzeile zu stammen. Sie verwenden Kernel-Releases, die auf den beiden Rechnern weit voneinander entfernt sind. Wenn der Code von einer Kernel-Header-Datei abhängt, ist möglicherweise eine Kernel-Version erforderlich, die neuer ist als auf der Red Hat-Maschine. Sie haben nicht angegeben, um welchen Code es sich handelt (handelt es sich um einen Gerätetreiber?) Oder um welche Dateien es handelt. Daher ist es schwierig, mehr zu sagen.
Vergleichen Sie die Inhalte von channel.h und internal.h auf den beiden Systemen, auf denen Sie unterschiedliche Ergebnisse erhalten. Ich bezweifle, dass das Problem die Version von gcc ist. Es ist wahrscheinlicher, dass die Fehler das Ergebnis von Codeänderungen dieser Dateien im Laufe der Zeit sind, z. B. wenn ein System über eine neuere Version einer Bibliothek und die zugehörigen Header-Dateien verfügt als die anderen.
Für den Anfang sprechen wir ein wenig über Ihr Problem. Ich denke, der wahrscheinlichste Grund dafür, dass Ihr System Fehler auf einem System gegenüber dem anderen verursacht, ist, dass der Code nicht identisch ist. Vielleicht möchten Sie dies mithilfe eines Tools oder des Befehls diff
überprüfen, um nach subtilen Änderungen zu suchen, die in Ihrer Codebasis aufgetreten sind.
Normalerweise, wenn ich Probleme mit diesem Fehlertyp gesehen habe, haben Sie etwas wie:
In einer Header-Datei und dann:
%Vor%in der Quelldatei. Das bedeutet, dass Sie einfach den Typedef in der Quelle ablegen können und es sollte OK sein. Nur etwas, wonach man suchen sollte.
Wenn nun ein gcc
issue ist, ist eine zweite Möglichkeit, Ihr Problem zu lösen, mehrere Versionen von gcc auf demselben Computer haben und dann die genaue Version von gcc
angeben, mit der über die Option -v
ausgeführt werden soll. Es könnte also eine gute Idee sein, 4.1.2 auf Ihrem Fedora 18-Rechner zu verwenden.
Eine weitere Anmerkung: Wenn Sie die Option -v
verwenden, aber nicht eine Version von gcc
angeben, erhalten Sie (auf der stderr-Ausgabe) die Befehle, die zur Ausführung ausgeführt werden die Etappen der Zusammenstellung. Dies könnte nützlich sein, um zu sehen, was passiert und ob es große Unterschiede zwischen den einzelnen Maschinen gibt.
Okay, jetzt zu Ihren Fragen. Ja, es gibt Flags zum Kompilieren auf "Version X" von gcc
:
Für den Anfang gibt es das __VERSION__
Predefined Macro , das wird dir zurückgespuckt werden const char *
der Versionsnummer. Dies kann sehr nützlich sein, aber wie die GCC-Dokumentation besagt:
Sie sollten sich nicht darauf verlassen, dass seine Inhalte eine bestimmte Form haben, aber es kann davon ausgegangen werden, dass sie mindestens die Release-Nummer
enthalten
Trotzdem habe ich in der Regel nur eine Ausgabeform gesehen, die so etwas wie "4.6.3"
ist, wenn meine Version von gcc
4.6.3-1ubuntu5
ist.
Wenn Sie jetzt wissen (oder vermuten), dass ein Teil Ihres Codes dazu führt, dass eine bestimmte Version von gcc
Fehler verursacht, können Sie die vordefinierten Makros __GNUC__
, __GNUC_MINOR__
und __GNUC_PATCHLEVEL__
zum "Schützen" verwenden. dich selbst:
Hier ist ein kurzer Ausschnitt, der auf höchster Ebene zeigt, wie man es benutzt:
Auf dem obigen System mit der Version 4.6.3 wird also die Meldung "Hello Version 4.x.x" angezeigt. Dann können Sie weiter fortgeschritten und überprüfen Sie auch die Subversionen:
%Vor%Oder die sauberere Version davon mit Ihrem eigenen Makro:
%Vor% Um Ihre Frage zu beantworten, ob verschiedene Versionen von gcc
zu unterschiedlichen Fehlern führen, haben Sie Recht, dass in jeder Version von gcc
mehr passiert und manchmal Dinge sich ändern, so dass Sie Unterschiede zwischen verschiedenen Versionen sehen des Compilers. Am besten ist es, die Versionshinweise für jede Version zwischen den beiden Versionen zu überprüfen. (von 4.1 bis 4.7).
Ich bin mir nicht sicher, welche Zielarchitektur Sie haben, also stellen Sie sicher, dass Sie diese spezifischen Abschnitte in jedem der Dokumente überprüfen. Aber ich denke, dass Sie sich wirklich die "Build system improvements"
und die "Incompatible changes to the build system"
ansehen wollen, sie machen auch einen Abschnitt, der spezifisch für C-Code ist.
Hier gibt es nicht genügend Informationen, um genau zu sagen, was vor sich geht. Ich schließe mich denen an, die sagen, dass es wahrscheinlich kein Problem mit der Compiler-Version ist.
Dieser Fehler tritt (offensichtlich) auf, wenn der Compiler zwei unterschiedliche Deklarationen für denselben Namen findet. Es sollte nicht zu schwer sein, herauszufinden, warum dies geschieht.
Überprüfen Sie das Makefile, um die Headerdateien internal.h
und channel.h
zu finden, auf die verwiesen wird. Die zitierten Zeilen haben eine typedef
oder eine andere Deklaration für channel_t
. Arbeiten Sie aus diesen Erklärungen heraus nach Hinweisen.
Ich muss davon ausgehen, dass sich eine oder beide dieser Dateien in Bibliotheken befinden, die Sie verwenden. Wenn sowohl internal.h
als auch channel.h
Ihr eigener Code sind, debuggen Sie Ihren eigenen Code!
Ansonsten gibt es viele Möglichkeiten. Am wahrscheinlichsten sind
Präprozessor -D
oder #define
ed Flags sind nicht korrekt, so dass mehrere Deklarationen bedingt kompiliert werden, wenn nur eine Deklaration erforderlich ist.
Zwei verschiedene Bibliotheken oder Standardheader und eine Bibliothek haben einen Namenskonflikt.
Ihr eigener Code kollidiert mit einer Bibliothek oder einem Standardheader. Wenn channel_t
ein von Ihnen definierter Typ ist, ist das ein Problem. Sie sollten keine eigenen Typen definieren, die auf _t
enden, da diese für die Implementierung reserviert sind.
Nummer 1 oben kann auf verschiedene Arten auftreten, aber am häufigsten ist die Fehlkonfiguration einer Bibliothek. Bibliotheken müssen normalerweise für das Betriebssystem, für das sie verwendet werden, ./configure
ed sein. Wenn Sie in einem Linux konfigurieren und zu einem anderen kopieren, fragen Sie nach Problemen wie dem, den Sie sehen.
Nummer 2 könnte auf einem Linux und nicht auf dem anderen auftreten, aufgrund von Versionsunterschieden zwischen den Bibliotheken. In diesem Fall aktualisieren Sie die Maschine mit dem Fehler auf die gleiche Version wie die ohne den Fehler. Vergessen Sie nicht, ./configure
auszuführen.
Für Nummer 3 ist die Lösung offensichtlich. Ändern Sie Ihren Typnamen.
Ich sehe ein channel.h
und channel_t
in Tor. Meine wilde Vermutung ist, dass Sie Tor verwenden und eine Tor-Fehlkonfiguration auf dem Computer mit dem Fehler betrachten.
Dies ist keine Frage, um den Fehler zu lösen, sondern eine allgemeine Frage Compiler.
Gibt es Flags, die ich einstellen kann, um dies in Zukunft zu vermeiden?
Jede spezifische Version eines Compilers wird mit eigenen Switches oder Flags ausgeliefert.
Wenn die Compiler-Version erstellt wurde, um bestimmte Switches zu akzeptieren, und eine davon ist diejenige, die Sie brauchen, um bestimmte Prüfungen Ihres Quellcodes zu vermeiden, dann gibt es / wäre eine Möglichkeit, dies in Zukunft zu vermeiden.
Wenn die Compiler-Version, die aktuelle oder zukünftige Version, die Sie verwenden, keinen Schalter hat, der bestimmte Prüfungen Ihres Quellcodes verhindert / überspringt, dann gibt es keine Möglichkeit, dies zu vermeiden.