C++Guns – RoboBlog

23.11.2017

C++ Guns: RE: Abstraction design and implementation: `repeat` Teil 1

Filed under: Allgemein — Tags: — Thomas @ 17:11

Hallo,
ich möchte hier ein paar Gedanken äußern zu dem tollen Artikel "abstraction design and implementation: `repeat`" von Vittorio Romeo [1].

Sein Ziel ist es eine simple for() Schleife, wie wir sie schon alle hingeschrieben haben, zu nehmen und zu verbessern. Das Problem bei einer voll ausgeschriebenen for() Schleife ist, dass sie zeigt WAS alles gemacht wird: Eine Schleifenvariable declakiert, initialisiert, incrementiert. Aber was willen wir eigentlich damit aussagen? Na, rufe die Funktion f() einfach 10 mal auf. Ahsoo!

for(int i=0; i < 10; ++i) {
    foo();
}

Das Problem an allen Codestücken die bis heute geschrieben worden sind, ist dass ihnen die Semantik fehlt. Der Code sagt immer nur auf, WIE etwas gerade verarbeitet wird, aber nicht WAS eigentlich getan werden soll. Wenn man Glück hat, steht das WAS in irgendeiner veralteten Dokumentation oder Kommentarzeilen die sich irgendwo befinden.

Aber in diesem Blogpost will ich nicht lehren zu Dokumentieren, sondern die Leute sensibel dafür machen, dass sie das, WAS sie wollen, auch genauso in Code ausdrücken können.

Kommen wir zurück zur for() Schleife.
In dem Code Beispiel oben steckt ziemlich viel low-level Technik. Es wird erst einmal eine Schleifenvariable i vom Typ int deklariert und mit 0 initialisiert. Und Stopp. Hier sind schon zwei lazy Bugs passiert.
Wer sagt denn, dass der Typ int sein soll? Wenn man über std::vector o.ä. Iteriert, sollte der Typ size_t sein, da std::vector::size() auch size_t zurück liefert. Und auch operator[] und at() jeweils ein size_t als Argument erwarten. Wenn ich eine Schleife aber nur 10mal laufen lassen will, dann ist der Typ int wiederum meist in Ordnung.

Die Initialisierung mit 0 ist auch nicht zwangsläufig richtig. Zwar fängt der Index in C/C++ bei 0 an, aber wenn man eine Schleife nur 10mal laufen lassen will, ist es doch egal ob man bei 0 anfängt und bis 9 zählt, oder ob man bei 1 startet und bei 10 endet.

Das bringt uns gleich zum nächsten lazy Bug. Der Ausdruck i < 10 ist so nicht intuitiv. Der Mensch beginnt nun mal bei 1 ab zu zählen und endet bei 10. Daher schreiben viele, noch nicht gefolterte C++ Programmierer, zurecht i <= 10.

Der nächste lazy Bug kommt noch in der selben Code Zeile. Ist es nun ++i oder i++? In diese Beispiel wäre es egal, da int ein POD ist. Ansonsten gilt, dass ++i vorzuziehen ist, da keine temporäre Variable erstellt (und evtl. wieder weg optimiert) werden muss.

Der letzte lazy Bug sehe ich leider auch sehr oft. Die Variable i wird nicht innerhalb der for() Schleife deklariert, sondern nur innerhalb der Funktion. Also altes C/Fortran. So ist es möglich, absichtlich oder aus versehen, die Variable i mehrmals zu nutzen. In der Regel ist dies nicht gewollt, und wenn doch, wird es nicht dokumentiert.

Es kann nicht sein, dass auf so viele Sachen geachtet werden muss, wenn eine simple Schleife gefordert ist. Vittorio Romeo zeigt zurecht wie es einfacher geht. Leider macht er so die Sache nicht besser, nur anders schlimm.

Teil 2

[1] https://vittorioromeo.info/index/blog/abstraction_design_implementation_repeat.html

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress