Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise



  • @axam sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Also wenn ich in meinem Code sage + - schleife, usw. kann ich aus meiner beschränkten sequenziellen Sicht heraus geistig nachvollziehen was genau mein Programm macht, welche Ergebnisse ich dort und da erwarte, und für mich sind es n-Schritte, die für eine Lösung nötig sind.
    Da der Compiler jedoch den von mir geschriebenen Code verändert bin ich gezwungen, daß ich darauf vertraue, daß der Compiler tatsächlich alles richtig macht.
    Sprich es besteht zumindest theoretisch die geringe Möglichkeit, daß ich im Code einen Fehler nicht finden kann, da das Programm fehlerfrei funktionieren würde wenn der Code 1:1 vom Compiler übersetzt wird.

    Das ist korrekt und auch durchaus realistisch. Compiler können Fehler haben, und manchmal haben sie auch wirklich welche die wirklich falschen Code erzeugen. Wir hatten z.B. einen Fall wo der Compiler falscherweise angenommen hat dass es an einer bestimmten Stelle keinen Overflow geben kann, und daher keine Notwendigkeit besteht ein 32 Bit Zwischenergebnis im 64 Bit Register auf 32 Bit zu maskieren. Das Ergebnis war dann eine viel zu grosse Zahl die hinten rausgekommen ist. (Und nur für alle dich sich jetzt denken "die haben sicher signed Integer Overflow gemacht, und das ist ja wohl UB": nein, das war alles unsigned.)

    Also ja, kann passieren. Ist aber sehr sehr selten. Das selbe kann BTW in der CPU selbst passieren, und auch da hat es Fälle gegeben wo CPUs falsch gerechnet haben (z.B. der berühmte Pentium fdiv Bug oder auch der Bug in Intels TSX Erweiterung). Dort ist es allerdings noch viel seltener als bei Compilern.

    Eine Möglichkeit die du allerdings bei Compilern hast ist ohne Optimierungen zu kompilieren. Dadurch macht der Compiler kaum bis gar keine schlauen Optimierungen mehr, und erzeugt Code der quasi 1:1 so funktioniert wie das was du hingeschrieben hast. Dadurch bleiben auch alle Schleifen und sinnlosen Operationen 1:1 erhalten. Wenn du einen Fehler beobachtest, und der auch mit nicht optimiertem Code auftritt, dann ist es sehr wahrscheinlich dass der Fehler in deinem Programm ist und nicht im Compiler. Wenn der Fehler nur im optimierten Programm auftritt ist es immer noch viel wahrscheinlicher dass er in deinem Code ist, aber dann ist es zumindest möglich dass es sich um einen Compiler-Fehler handelt.



  • @axam sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Wovon ich spreche ist, wenn der Compiler genau das macht was er immer macht, und in der Regel dieses Verhalten auch erwünscht ist, jedoch in einem ganz speziellem Fall die Codeänderung zum Ursprung eines Fehlers wird.

    Wenn eine Optimierung in einem speziellen Fall zu falschem Verhalten führt, ist das auch ein Bug im Compiler.
    Mir ist bisher in meiner Laufbahn noch kein Compilerfehler untergekommen, ich kenne nur Fälle aus der Literatur.
    Tatsächlich bist du, wenn du Software entwickeln willst, darauf angewiesen, dass die CPU funktioniert wie spezifiziert, der Compiler funktioniert wie erwartet, das das OS funktioniert wie erwartet und das irgendwelche 3 Party Libs funktionieren. Bei letzteren stolpert man schon mal über Fehler, alles andere funktioniert recht gut.

    Wenn du alles selbst machen möchtest, viel Spaß beim Löten von Schaltkreisen 😉 Aber, selbst machen heißt noch lange nicht, dass es hinterher Fehlerfrei ist, dann ist man nur wirklich auch selbst Schuld.


  • Mod

    @Schlangenmensch sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Wenn eine Optimierung in einem speziellen Fall zu falschem Verhalten führt, ist das auch ein Bug im Compiler.
    Mir ist bisher in meiner Laufbahn noch kein Compilerfehler untergekommen, ich kenne nur Fälle aus der Literatur.

    Das erinnert mich an die fast-floating-point-math-Optimierung vieler Compiler, die viele Leute aktivieren, ohne die Doku genau zu lesen, unter welchen Sonderumständen diese Optimierung zu (dokumentiert!) anderem Verhalten führt. Und sich dann wundern. Hat mich schon viel Zeit gekostet, Kollegen damit zu helfen, die selber dachten, einen Compilerbug gefunden zu haben.



  • @Schlangenmensch sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Tatsächlich bist du, wenn du Software entwickeln willst, darauf angewiesen, dass die CPU funktioniert wie spezifiziert, der Compiler funktioniert wie erwartet, das das OS funktioniert wie erwartet und das irgendwelche 3 Party Libs funktionieren. Bei letzteren stolpert man schon mal über Fehler, alles andere funktioniert recht gut.

    Du schreibst "recht gut". Das kann ich so unterschreiben.

    Speziell beim OS sind Fehler aber gar nicht so selten. Da hab ich schon mehr als einen in Windows gefunden.

    Compilerfehler die zu Fehlermeldungen bei korrektem Code führen hab ich auch selbst bereits einige gefunden. Einen sogar der zu falschem Code führt (falscher Overload ausgewählt). Compilerfehler wo so richtig "falsch gerechnet" wird hat wie schon geschrieben ein Kollege von mir einen gefunden, davon abgesehen kenne ich es auch nur aus der Literatur.

    Und schliesslich CPU Fehler kenne ich auch nur aus der Literatur/Internet. Weder selbst einen gefunden noch kenne ich persönlich jmd. der einen gefunden hat.

    Also Zuverlässigkeit ist mMn. recht eindeutig CPU > Compiler > OS > Third-Party Libs & alter (bewährter) eigener Code > neuer eigener Code.

    ps: @axam Ich mach den Job jetzt aber seit > 20 Jahren, also lass dich nicht schrecken/entmutigen. Was @Schlangenmensch geschrieben hat stimmt schon - das Zeug funktioniert schon recht gut.


  • Mod

    @hustbaer sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    ps: @axam Ich mach den Job jetzt aber seit > 20 Jahren, also lass dich nicht schrecken/entmutigen. Was @Schlangenmensch geschrieben hat stimmt schon - das Zeug funktioniert schon recht gut.

    Es gibt da natürlich noch eine ganz andere Kiste, nämlich inwiefern du den Machern all dieser Dinge vertrauen kannst, und ob du überhaupt prinzipiell(!) prüfen könntest, ob das Vertrauen gerechtfertigt ist: https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf



  • @hustbaer sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Compilerfehler die zu Fehlermeldungen bei korrektem Code führen hab ich auch selbst bereits einige gefunden. Einen sogar der zu falschem Code führt (falscher Overload ausgewählt). Compilerfehler wo so richtig "falsch gerechnet" wird hat wie schon geschrieben ein Kollege von mir einen gefunden, davon abgesehen kenne ich es auch nur aus der Literatur.

    Das ist bei MSVC in letzter Zeit recht schlimm geworden, zumindest wenn man sich gleich die vorgeschlagenen VS Updates installiert. "Lustig" fand ich paar dead code elimination Bugs hintereinander. Hat viel Zeit gekostet, den Bug zu finden (in einer third party Bibliothek), dann haben wir gefunden, dass den schon jemand gemeldet hatte, dann wurde in dem Ticket rumdiskutiert und Begründung war irgendwie, die dead code elimination hat offensichtlich nötigen Code wegoptimiert.
    Nächstes SP mit dem Bugfix installiert, anderer Bug in einer anderen third party aufgefallen... Und dann wieder dead code elimination als Begründung 🙂



  • @axam sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Wenn ich nur wissen will, wie viele Äpfel ich habe, sind es immer 24, es macht semantisch jedoch einen unterschied ob ich 4 Packungen habe mit je 6 Äpfeln, oder 6 Packungen mit je 4 Äpfeln.

    Du übergibst dem Compiler aber nicht Packungen mit Äpfeln, seiner eine mathematische Anweisung. Dein Jobs ist es die Formeln entsprechend zu formulieren. Mathematisch ist 4×6 gleich mit 6×4, in der besonderen Zahlendarstellung eines Computers dürfte der Compiler die Mulitplikation mit 4 auch durch ein Bitshift ersetzen, auch das wäre mathematisch das Gleiche.

     6 = 00000110;
     4 = 00000100;
    24 = 00011000;
    

    Aber es bleibt jedoch, ab dem Punkt des Compilieren verliere ich die Kontrolle über den Code. Ein Fehler resultiert somit nicht nur ausschliesslich aus einer fehlerhaften Logik meines Codes,

    Compilerfehler sind sehr selten, d.h. fast immer wird es ein Problem mit der Logik Deines Programmes geben und nicht mit dem was der Compiler für Optimierungen übernimmt. Wenn Dein Programm trotz fehlerfreier Übersetzung sich durch Optimierungen anders verhält hast Du UB eingebaut, und genau das gilt es zu vermeiden.



  • @Schlangenmensch sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    Mir ist bisher in meiner Laufbahn noch kein Compilerfehler untergekommen, ich kenne nur Fälle aus der Literatur.

    Ältere GCC Versionen haben mit -O3 gerne Unsinn erzeugt und zwar stochastisch. D.h. zuweilen kam ein superschnelles korrektes Programm heraus, und man anderen Läufen nur Unsinn. Da waren experimentelle Optimierer dabei, die noch instabil waren.



  • @SeppJ sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    @hustbaer sagte in Informationen finden zu: BasicLowLevel C++ / Interne Funktionsweise:

    ps: @axam Ich mach den Job jetzt aber seit > 20 Jahren, also lass dich nicht schrecken/entmutigen. Was @Schlangenmensch geschrieben hat stimmt schon - das Zeug funktioniert schon recht gut.

    Es gibt da natürlich noch eine ganz andere Kiste, nämlich inwiefern du den Machern all dieser Dinge vertrauen kannst, und ob du überhaupt prinzipiell(!) prüfen könntest, ob das Vertrauen gerechtfertigt ist: https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf

    Huch, ja, darüber hab ich noch gar nie nachgedacht. So lange man aber nicht davon ausgeht dass alle Compiler verseucht sind, kann man sich behelfen indem man einen Compiler mit einem anderen Compiler übersetzt und erst dann mit sich selbst.



  • @Mechanics Ja, wir haben auch unsere Freude mit MSVC. Ich finde zwar die schnellen Feature-Updates toll, aber was ich gar nicht toll finde ist dass es keinen "stable branch" mehr gibt. Bugfixes kommen jetzt mit dem nächsten Update, mit dem auch neue Features kommen und dadurch neue Bugs. Hmpf.


Log in to reply