Grundsätzlich IMMER testen, auch wenn es ein Miniprogramm mit einer einzigen super kurzen Funktion ist.

Mein Testcode ist im Schnitt 10 bis 50 mal umfangreicher als der zu testende eigentliche Programmcode, und ich achte strikt auf eine 100%ige Testabdeckung.

Die meisten Entwickler sind aber leider zu faul dazu und schreiben keine Mocks / Stubs / Spies, bzw. geben sich mit 90% oder gar weniger Testabdeckung zufrieden.

Wie wichtig glatte 100% sind merkt man jedoch erst richtig, wenn man in den letzten 10% haufenweise teils schwerste Bugs findet, die man bei "normalem" Testen übersehen hätte.

Lustig ist auch immer, wenn einem die 90%-Tester erzählen, dass 100% Testabdeckung übertrieben bzw. unnötig seien, ohne zu erkennen, dass man dann eben 1000 von 10000 Zeilen Code ungetestet in die Außenwelt entlässt.

Aber wie gesagt, die meisten Entwickler testen nicht so gründlich.

In meiner Firma haben wir übrigens noch nie einen wirklichen Bug gemeldet bekommen, obwohl wir in einer Nische weltweit die Standardsoftware stellen.

Natürlich ist auch unsere Software NICHT komplett Fehlerfrei, aber dass Bugs NACH dem Release gefunden wurden, kam in über 10 Jahren noch nie vor.

Und dennoch wird man als Verfechter 100%iger Testabdeckung schief angeguckt, weil es angeblich nicht wirtschaftlich sei und bla bla bla.

Dass wir jetzt Marktführer in unserem Segment sind und weltweit die gesamte Konkurrenz verdrängen konnten, liegt m. M. n. fast ausschließlich an der überragend hohen Qualität, auch wenn zum Testen von drei Zeilen eben mal 5 Seiten Testharness gebaut werden müssen, die zum größten Teil selbst erstmal ausgiebig getestet werden müssen.

Richtiges Testen ist eine hohe Kunst, die leider allzu oft unterschätzt wird. Bei uns kommen auf einen Programmierer zwei bis drei Tester.

Also um deine Frage zu beantworten:

Immer testen. Alles. Und zwar 100%. Auch Hobbyprojekte. :)

...zur Antwort

Durch solltest puffern, ansonsten arbeitet dein Code nämlich sehr langsam.

Außerdem wird end_file nicht geschlossen.

Und du solltest Modulo nutzen.

...zur Antwort

Du kannst 10.45 nicht als Double darstellen. Das ist unmöglich.

Runde einfach bei der Ausgabe, oder nutze Fixpunkt.

...zur Antwort

Makros wie INT_MIN usw. aus <climits> sind in C++ seit fast 10 Jahren veraltet.

Nimm lieber ...

numeric_limits<int>::min()

... usw. aus <limits>, denn das hat unzählige Vorteile, auch wenn du die als Einsteiger zu großen Teilen noch nicht verstehen können wirst! :)

...zur Antwort

Jein, es gibt zwar formal bugfreie Software in sehr geringem Umfang, aber irgendwann werden auch in der besten Hardware Bitflips auftreten, und dann wars das mit der Fehlerfreiheit.

Rowhammer nutzt das bewusst aus, um ausnutzbare Fehler in eigentlich (!) Bugfreie Software zu reißen.

Also ja, es geht und wird manchmal auch so im Automotivebereich gemacht, ist in der Praxis aber keine Garantie.

...zur Antwort

Das geht recht schnell, aber dass offensichtlich selbst Firmen, die "Advanced Systems" im Namen tragen, haufenweise Anfängerfehler machen und trotz Zertifizierung gegen so ziemlich alles verstoßen, was man unter "sicherer Programmierung" versteht, siehst du an dem Straublink aus der anderen Antwort.

Deshalb sind sog. Zertifizierungen meist das Papier nicht wert, auf dem sie gedruckt sind.

...zur Antwort

Kleine Werkzeuge kompiliere ich mir statisch in eine ELF ohne Section-Header.

Das hat den Effekt, dass die Binary auf allen Kerneln seit 1.x unverändert läuft, und du nur ein einziges Binary-File ausliefern musst.

Da du ohne Kopfstände aber nicht verhindern kannst, dass der Linker (libdl.so usw.) in Form von einiger Hand voll Pseudo-Bibliotheken geladen wird - was wieder Systemspezifisch ist - wird diese Methode für dich nicht praktikabel sein.

Dazu habe ich auch nichts im Netz gefunden, sondern mich selbst durch die Einstellungen für Compiler und Linker gequält.

Fakt ist, es ist möglich, eine einzige Binary zu erzeugen, die unverändert auf alten und zukünftigen Distributionen laufen wird, aber das wird hier den Rahmen bei weitem sprengen.

Eine weitere noch einfachere Möglichkeit ist, deinen Code in eine (statische oder dynamische) Bibliothek zu packen und ein leichtgewichtiges Makefile mit auszuliefern, welches eine Executable drum rum baut.

Die dritte und m. M. n. beste Möglichkeit wäre einfach ein Tarball und dem Endnutzer den Hinweis "make" zu geben.

Von Containern halte ich perösnlich nichts, da total monströs aufgeblasen. Das steht fast nie in einem Verhältnis zum Nutzen ... sehen die meisten Leute aber wohl anders.

Und Formate wie Snap & Co sind mir persönlich viel zu unsauber konzipiert, aber man kommt ja leider oft nicht drum herum.

Naja, musst du selbst eintscheiden, was du favorisierst, aber ich denke, am Ende wirst du bei Containern oder einem deiner oben genannten Formate landen. :)

...zur Antwort

Mach doch lieber einen DNS Lookup mit entspr. Timeout.

Selbst auf einem 10 Jahre alten Laptop kannst du damit viele Tausend Domainnamen pro Sekunde prüfen.

Ein HTTP Request ist eigentlich total unnötig.

...zur Antwort

Einige kleine Anmerkungen, nicht nur für den Fragensteller, sondern für alle mitlesenden Softwareentwickler:

  1. In deinem String musst du "\d" mit Doppelslash (also "\\d") escapen, es sei denn, du nutzt rohe Strings.
  2. RegEx wird überbewertet. In deinem Falle ist ein parsen von vier Integern schneller, sauberer und zuverlässiger.
  3. IP-Adressen sollte man als ahnungsloser Entwickler NIE selbst überprüfen, sondern diese Aufgabe den APIs überlassen, die Wissen was sie tun und entspr. Fehler abfangen. (Das gleiche gilt auch für Mailadressen!)
  4. Eine gültige Form für Localhost ist "127.1", obwohl du vermutlich nur "127.0.0.1" kennen wirst.
  5. Die IP "12.34.5678" ist gültig. (Beachte, das letzte Element, welches größer als 255 ist!)
  6. Auch die IPs "1" oder "1234567890" sind gültige IPv4 Adressen. Und diese Formate sind nicht mal exostisch, sondern durchaus üblich!

Merke: Textuelle Repräsentationen von gewissen Daten sollte man nur prüfen, wenn man auch die RFC oder die Spezifikation dazu gelesen hat.

Funfact: Ich habe schon mehrere tausend Zeichen lange RegEx-Orgien zur Verifikation von E-Mails gesehen, aber noch keine davon hat valide Formate erkannt, die ich mir aus den Fingern gesaugt habe.

Es ist zwar rein theoretisch möglich, alles mögliche mit Regexen zu validieren, aber in der Praxis artet das selbst bei scheinbar (!) trivialen Problemen extrem aus, wenn man es "richtig" machen will.

Du solltest dich damit zufrieden geben, solche Formate nur ganz grob zu testen, und den Rest der API zu überlassen, die letztendlich damit arbeiten muss, und deren eventuelle Fehler abfangen.

Beispiel: Eine Mailadresse sollte als eine solche akzeptiert werden, wenn ein '@' drin vorkommt. Mehr nicht. Das wars. (Genau genommen ist selbst das schon zu viel, aber ich will das jetzt nicht übertreiben.)

Und eine IP sollte dann als gültig akzeptiert werden, wenn eine Ziffer drin vorkommt.

In beiden Fällen (Mailaddr. und IP) wäre jede weitere Prüfung darüber hinaus, eine Einschränkung und somit ganz eindeutig ein Bug, der valide Eingaben fälschlicherweise als ungültig ablenen würde.

So, das wars. :)

...zur Antwort

Natürlich. Normalerweise macht man das auch so.

Du musst dazu deine Threads / Prozesse synchronisieren. Vermutlich willst du einen Mutex nutzen, wenn es um einen Logger geht, der in Dateien schreibt.

Allerdings schreibst du C++ und fwrite, was aber nicht so richtig zusammen passt. Bei C nutzt man fwrite, bei C++ lieber ofstream-Objekte.

fwrite hat viele Nachteeile, und nur weil du du in C++ auch C-Funktionen nutzen kannst, macht das noch lange keine C++ Programmierung.

Ein ofstream bietet Exceptions und dank RAII musst du dich nicht um ein fclose() kümmern.

Aber egal ... lerne lieber erst mal vernünftig C++ mit einem guten Lehrwerk (Buch oder Tutorial), sonst bringt dich das ganze Gefrickel nicht weiter und du wirst zeitnah genervt aufgeben.

Viel Erfolg! :)

...zur Antwort

Das wird mit Java schwierig bis unmöglich, abhängig davon, was du unter "Crash" verstehst.

Wenn es dir aber nur um einen Absturz der JVM geht, dann achte darauf, den Schreibvorgang in eine Datei auf jeden Fall mit dem darunter liegenden Dateisystem zu synchronisieren.

Und damit sind wir schon an einem Punkt angelangt, an dem "Compile once, run anywhere" nicht mehr gilt, denn dafür musst du Funktionalitäten nutzen, die spezifisch für das jeweilige Betriebssystem sind.

Im einfachsten Falle feuerst du über einen weiteren Prozess einfach ein "sync" Kommando ab, auch wenn das etwas pfuschig wäre.

Auf jeden Fall wird die flush() und schon gar nichtt die close() Methode deines Streams oder RandomAccessFile nichts bringen, falls du unter "Crash" auch Dinge wie Kernel-Panics verstehst.

Allerdings gibt es eine einfache Lösung für dein Problem: Einfach sauber und fehlerfrei programmieren. Das erreicht man mit Tests die eine ausreichende Code-Abdeckung haben. Dann stürzt auch nichts mehr ab.

Anstatt also deine Fehler zu umschiffen, beseitige sie doch einfach. :)

...zur Antwort

Ich habe mir selbst Assembler ab der zweiten Klasse beigebracht, und in den darauffolgenden Jahren noch einige "richtige" Programmiersprachen, aber einen Programmierunterricht in der Grundschule (momentan bis zur 4ten Klasse?) halte ich nicht für zielführend.

Ich denke, den Kindern wäre VIEL mehr geholfen, wenn man ihnen ab der dritten Klasse die Grundlagen der Aussagenlogik und Mengenlehre beibringen würde, denn das ist (auf einfachem Niveau) nicht sonderlich anspruchsvoll, hilft zukünftig aber nicht nur bei Mathe enorm weiter.

Wahrheitstafeln ausfüllen und Venn-Diagramme studieren ist jetzt nichts, was man nicht spätestens in der dritten Klasse packen würde, wobei die meisten Kinder das meiste davon sicher schon in der ersten Klasse hinkriegen würden.

Aber Programmieren? Da sehe ich so früh den Nutzen nicht. So ab 12 Jahren wäre es akzeptabel, denke ich, aber erst ab 14 wirklich sinnvoll.

Aber das wird jeder anders sehen. :)

...zur Antwort

Natürlich nie. Unter gar keinen Umständen.

Ein Deadlock ist eine der schlimmsten Bugs, die man sich vorstellen kann.

Wenn in einer Software Deadlocks (auch nur theoretisch) aufteten könnten, dann ist das Design kaputt und erfordert eine grundlegende Überarbeitung.

Die Frage stellt sich also gar nicht, es sei denn man ist ein notorischer Pfuscher. :)

...zur Antwort

Bei C gibt es dafür die sprintf-Familie, vornehmlich in Form der "Secure-Varianten".

Da du aber C++ nutzt, solltest du alle printf-Funktionen komplett vergessen, und es lieber so machen, wie man es normalerweise in C++ macht, nämlich mit std::stringstream aus dem <sstream> Header. :)

...zur Antwort