C++Guns – RoboBlog

27.02.2017

C++ Guns - Auto Variables - Gute Beispiele

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

GotW 93 von Herb Sutter finde ich sehr gut. Es wird eine Reihe von Möglichkeiten für "auto" anhand von Beispielen gezeigt und erläutert. Das erleichtert das Programmieren wirklich sehr. Schon 1983 wurde "auto" von Bjarne Stroustrup in C++ implementiert. Aber dank dem schon damals schrottigem C musste er es wieder raus nehmen. Na, ich bin sehr froh post C++11 zu leben.

GotW 93

Es gibt auch eine Situation, in welche "auto" auf den ersten Blick ein falschen Typ ableitet. Aber bei genauerer Betrachtung ist es das alte Problem von unterschiedlichen integer Typen. Also unsigned long int + signed int = unsigned long int. Der unsigned long int Datentyp ist "stärker" als signed int. Diese Definition geht auf die Anfängen von C zurück. Und es gibt keine Lösung die alle Fälle abdeckt. Es können weder signed Werte in unsigned long dargestellt werden, noch passen unsignled long in signed int rein. Aber jedesmal auf under/overflow zu prüfen ist einfach nicht effizient genug. Auch "auto" wird dieses Problem nicht lösen. Aber es eliminiert die Folgefehler.

Wie erwähnt, ist der Ergebnistyp bei der Subtraktion von unsigned long und signed int wieder ein unsigned long, obwohl der Programmierer ein signed int als Ergebnis haben wollte. Ohne die Benutzung von "auto" ist das auch einfach zu erreichen. Aber es ist nicht ersichtlich, dass im Code ein versteckter Fehler lauert:


unsigned long x    = 42;
signed short  y    = 43;
int diff = x - y;

Also das ist das reinste Kudelmuddel. unsigned long und signed short gehn rein, und signed int kommt raus. Jetzt kann das Ergebnis wegen unsigned long aber größer sein, als ein int speichern kann. Und mit der Benutzung von "auto" ist der Ergebnistyp wieder unsigned long und kann damit keine negativen Werte speichen, obwohl das offensichtlich gewollt ist.

Als Ergebnistyp würde signed long am besten passen. Aber erklär das mal den Programmierer, und dokumentiere diesen Pitfall an 1000 Stellen im Code, so dass es auch in 30 Jahren noch nachvollziehbar ist: no way!
Andrei Alexandrescu Idee finde ich hier sehr schön. Wir lassen natürlich den Compiler die Arbeit für uns machen! Der Compiler hat schon die Information, dass der Ergebnistyp ein long sein muss. Das ein signed Typ gewollt ist, sagt der Programmieren. In Kombination mit C++11 std::make_signed, welches für jeden gegebenen integral Typ, einen signed integral Typ ausspuckt, lassen sich schön zwei Hilfsfunktionen erstellen.


// C++14 version, option 1
template auto as_signed  (T t){ return make_signed_t  (t); }
template auto as_unsigned(T t){ return make_unsigned_t(t); }

auto diff = as_signed(x - y);

Durch diesen Einzeiler wird der bestmögliche Typ abgeleitet und gleichzeitig spricht der Code, dass hier was besonderes mit der Arithmetik passiert.

/// \todo Beispiel Code der zeigt was mit const und referenzen passiert.

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress