Deleter shared_ptr, lambda expression, member variable



  • Funktionen sind ein haufen Bytes die irgendwo im Speicher rumliegen - die werden nicht modifiziert. => Da kann's kein Race geben.
    Auf den Stack gelegt wird eine Funktion auch nicht. Höchstens ihre Parameter, lokalen Variablen, die Rücksprungadresse -- solche Dinge.

    Abgesehen davon kann sich eine Funktion über static Variablen o.ä. natürlich selbst ins Knie schiessen kann. Das Problem dabei sind dann aber wieder die Variablen, nicht die Funktion.

    Was deine erste Frage angeht: es gibt z.B. den ThreadSanitizer ("TSAN"):
    http://code.google.com/p/data-race-test/wiki/ThreadSanitizer
    Und natürlich noch weitere $$$ Tools von Borland, Intel etc.
    Der "korrekte" Weg ist aber zu wissen was man tut, und dann einfach funktionierenden Code zu schreiben.

    EDIT: Und diesen dann ggf. mit solchen Tools nochmal zu überprüfen, das ist natürlich eine sehr gute Sache! Dein Beitrag liest sich allerdings irgendwie nach "ich programmier einfach mal irgendwie, und dann dreh ich das so lange durch mein Debugging-Tools, bis das die Schnauze hält." Und das halte ich für weniger gut 😉



  • hustbaer schrieb:

    EDIT: Und diesen dann ggf. mit solchen Tools nochmal zu überprüfen, das ist natürlich eine sehr gute Sache! Dein Beitrag liest sich allerdings irgendwie nach "ich programmier einfach mal irgendwie, und dann dreh ich das so lange durch mein Debugging-Tools, bis das die Schnauze hält." Und das halte ich für weniger gut 😉

    So extrem ist es sicherlich nicht, aber eben ein Geben und Nehmen. 😉

    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.

    Ob es auch wirklich robust ist, zeigt sich dann durch ausprobieren: Mal extreme Werte für Variablen eingeben oder eben z.B. Valgrind drüberlaufen zu lassen, ob der Speicherlecks findet, die nur durch Glück nicht direkt zu Segmentation Faults geführt haben.

    Ansonsten gebe ich dir recht, dass es echt Arbeit ist sich den Aufbau eines Programms zu überlegen: Welche Klasse verwaltet was und wie werden z.B. Informationen von wem zu wem weitergegeben.

    Gruß,
    -- Klaus.



  • 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.


Anmelden zum Antworten