On Don, 2001-09-13 at 11:50, Thomas Hertweck wrote:
Hallo Christoph,
Christoph Maurer wrote:
Hat jemand von Euch detaillierte Kenntnisse zum gcc/g++ und insbesondere dem optimierten Kompilieren.
Wuerde ich von mir jetzt nicht gerade behaupten, trotzdem eine kurze Antwort von mir auf diese Mail.... :-) Dito :)
Ich kenn mich zwar einigermassen mit gcc/g++ aus, doch von den Optimizern habe ich nur wenig Ahnung :(
Habe hier eine C++-Datei (2800 Zeilen, 2 große und ca. 15 kleine Funktionen), die sich mit -g wunderbar übersetzen läßt, sobald ich sie aber optimiert übersetzen will, scheitert das (Sowohl mit -O als auch mit -O2). [...]
Ein aehnliches Phaenomen hatte ein Kollege von mir hier am Institut auch schon. Der Code war mit Debugging Flag und auch unoptimiert ohne Probleme zu compilieren, mit Optimierung jedoch ging gar nichts mehr. Das Problem damals waren IIRC verkettete Listen. Das ist allenfalls der Auslöser nicht aber die Ursache. Die eigentliche Ursache sind Bugs im Compiler. Wo ist nur schwer zu sagen.
Er hat das Problem dann mehr oder weniger durch Ausprobieren geloest, sprich: irgendwie muss man he- rausfinden, welcher Teil des Quellcodes beim Optimieren Aerger macht und den dann noetigenfalls abaendern. Das Ganze ist glaube ich eine Wissenschaft fuer sich, ob es da eine allgemeine Herangehensweise gibt, weiss ich nicht. An einer Loesung oder Strategie, das Problem systematisch einzugren- zen, waere ich daher auch interessiert. Der einzig systematische Weg wäre gcc zu debuggen.
Um Fehler im Compiler einzugrenzen hilft es meist mit Compilerflags zu spielen. Um Workarounds zu finden, hilft einzig Erfahrung und die gcc und binutils Listen zu verfolgen (Was ich jedem, der ernsthaft SW mit gcc und binutils entwickelt, nur dringend nahelegen kann). Um die Auslöser im Quellcode zu finden, ist es sehr hilfreich, betroffenen Code erst "präprozess-ieren" zu lassen (gcc -P -E) und anschliessend getrennt zu übersetzen. Man kann dann oft durch systematisches Löschen von Code im "präprozessierten" Code oft ein minimiertes Beispiel konstruieren, dass es dann entweder erlaubt, einen Workaround zu finden, oder aber den gcc-Spezialisten hilft einen Bug einzukreisen. Im speziellen Fall (komplexe C++-Templates) hilft es oft typedefs, typename oder Klassen zu benutzen, statt kaskadierte Templates zu verwenden. Ansonsten gibt es bei allen gcc Versionen bekannte Fehler. Hier hilft oft ein Blick in die Archive der gcc und binutils Listen. Von gcc-2.95.x ist auch bekannt, dass er, was c++ angeht, zwar deutlich besser als seine Vorgänger ist, doch aber an einigen Stellen (insb. Templates und Namespaces) in Einzelfällen heftige Probleme hat. Das war übrigens auch mit ein Grund, warum RH bei RH-7.x eine inoffizielle, auf damals aktuelle gcc-Entwicklerversionen aufsetzende pre-3.0 Version (jetzt gcc-2.96 genannt) zu verwenden, da die RH-Leute den gcc-2.95.x damals als inakzeptabel empfanden. Die gleichen Probleme mit gcc-2.* waren auch ein Grund, warum gcc-3 entwickelt wurde, der, was den C++ Support angeht, gcc-2.* weit überlegen ist, nur in der Summe (insb auf Nicht-ix86-Architekturen) noch reichlich unausgereift ist. Für aktuelle Entwicklungen unter Linux ist er allerdings durchaus brauchbar (Ich verwende ihn selbst :)) Ralf