Gerade was Data-Races angeht ist es aber relativ einfach korrekten Code zu schreiben.
Wenn man auf Atomics und andere fancy-schmanzy Sachen verzichtet, und überall brav Mutexen verwendet, dann hat man keine Races.
Ausser man vergisst irgendwo komplett zu synchronisieren, und diese Fälle werden von TSAN oder ähnlichen Tools noch am Besten gefunden.
(Wenn man nämlich versucht selbst über Atomics zu synchronisieren, und dabei Mist baut, dann kann es sein dass die Tools die noch vorhandenen Races nicht mehr erkennen können. Oder, je nach Tool, dann haufenweise False Positives ausspucken.)
Was viel schwieriger ist, ist ein Programm zu schreiben das keine potentiellen Deadlocks enthält.
Klaus82 schrieb:
Ich muss gestehen, dass mir dies am Programmieren ziemlich gut gefällt, ob etwas funktioniert lässt sich direkt daran erkennen, ob es kompiliert und beim Laufen die erwarteten Ergebnisse produziert.
Ich schreib fast nur Code der "unattended" läuft. Serverprogramme, Software für Unterhaltungsspielautomaten - solche Dinge.
Da müssen nicht nur alle Corner-Cases abgedeckt sein, sondern auch die Fehlerbehandlung passen.
Und Leaks darf man auch keine haben.
Das sind Dinge die man mit "schnell mal ausprobieren" nicht verifizieren kann.
Natürlich wäre hier ganz klar TDD angesagt, das ist ja im Prinzip auch "ausprobieren" -- nur halt viel viel aufwendiger als wenn man einfach nur das fertige Programm testet, ohne zu genau auf Corner-Cases einzugehen.
Wissen was man tut, und wie man Dinge aufbauen kann so dass die Chance von schweriwegenden Bugs stark reduziert wird macht sich da schon bezahlt.