Das Internet wimmelt von Codeschnippseln für alle möglichen Anwendungszwecke. Darunter befinden sich sowohl brilliante Lösungen wie furchtbare Ideen, die vielleicht auf Anhieb funktioniert haben, aber absehbar zu großen Problemen führen werden. Selbst im Quellcode von ernsthaften Projekten finden sich zuweilen derartige Implementationen, wenn das Projekt aus den ersten Gehversuchen eines Programmierers stammt, oder dieser einfach ein Brett vor dem Kopf hatte. Dieser Artikel stellt eine kommentierte kleine Sammlung von derartigen schlechten Einfällen dar – gleichsam als Warnung und zur Unterhaltung – auf das künftig andere Fehler gemacht werden, die ich dann auch hier aufnehmen kann.
Wenn man gerade keine Warte-Funktion in der Standardbibliothek zur Hand hat, wird immer wieder gerne auf Busy-Wait (dt.: geschäftiges Warten) zurückgegriffen, also eine
Implementation, die die zu überbrückende Zeitspanne damit verbringt, die Rechenzeit zu verbrennen. Dass das keine ideale Lösung ist, muss ich wohl nicht
näher erläutern, und seit C++11 std::this_thread::sleep_for()
eingeführt hat, entfällt auch der letzte Grund dafür, eine solche
Implementation zu verwenden: Plattformunabhängigkeit. Der Autor folgender Zeilen hat es jedoch bedauerlicherweise nicht einmal geschafft, ein plattformunabhängiges
Busy-Wait zu implementieren, denn die Einheit des Rückgabewerts von clock()
ist platformabhängig und hätte mit CLOCKS_PER_SEC
skaliert werden müssen...
void sleep(unsigned int milliseconds) { clock_t end = milliseconds + clock(); while (end > clock()) ; }
„Wenn mir die Zufallszahl nicht passt, dann mach' ich mir halt eine Neue!“, dachte wohl der Autor folgender Funktion, die eine ganzzahlige Zufallszahl innerhalb eines bestimmten Wertebereichs liefern soll:
int clamped_rand(int bottom, int top) { int i = rand(); while (i > top || i < bottom) i = rand(); return i; }
Solange also die Zufallszahl nicht im gewünschten Bereich liegt, wird einfach immer eine Neue erzeugt. Die Funktion liefert auch tatsächlich eine gleichverteilte
Zufallszahl im gewünschten Bereich – wobei offen bleibt, wie lange sie dafür wohl braucht. Gewissermaßen ist an diesem Generator alles zufällig, denn die Laufzeit
dieser Funktion ist vom (Pseudo-)Zufall abhängig, und je kleiner der
Wertebereich, desto wahrscheinlicher ist, dass die Funktion eine lange Laufzeit hat. Mit einer gewissen Wahrscheinlichkeit kann die Funktion also auch mal einen Tag für
die Ziehung brauchen, wenn die Sterne gerade schlecht stehen und stundenlang keine Zufallszahl im Zielbereich gezogen wird. Wonach der Programmierer eigentlich suchte
– zumal es im konkreten Anwendungsfall keiner exakten Gleichverteilung bedurfte –, war folgendes (wobei es seit C++11 noch technisch bessere Lösungen aus
<random>
gibt, die dann auch wirklich gleichverteilt sind):
int clamped_rand(int bottom, int top) { return bottom + rand() % (top - bottom + 1); }