Using Namespace

Und wieder geht ein Tag voller Heldentaten zu Ende … die keiner bemerkt hat.

Über 3 Stunden mühsame Tipparbeit sind vollbracht um die Sünden von 10 Jahren Achtlosigkeit zu beheben.

Warum zur Hölle verwenden so viele Leute “using namespace”?


Leider steht es ja auch so meinem allerersten C++ Buch von 1998 so drinnen:

 1#include <iostream.h>
 2
 3using namespace std;
 4
 5int main()
 6{
 7  cout << "Hello World";
 8  return 0;
 9}

Und dieses Krebsgeschwür infiziert bis heute Sourcen in aller Welt … und ganz besonders in internen bzw. proprietären Programmen in Unternehmen.

Vor unserer Zeit

Tatsächlich waren Namensräume vor der Standardisierung 1998 kein weit verbreitetes Feature. Auf cin und cout hatte man sich schon verständigt, aber nicht auf std.
Und als der Standard festgelegt wurde, wurden viele Softwarestücke zum Non-Standard, weil sie std eben nicht kannten.

Die Lösung war also:

Schreibt einfach using namespace std; in alle Header, dann läuft wieder alles.

Heute (eigentlich gestern)

Und dann kam BOOST und dann kamen C++11, C++14 und seine weiteren Geschwister.
Auch Applikationen, die BOOST nutzen, pflegen die Unart using namespace boost; zu schreiben, um alle seine Klassen in den globalen (bzw. eigenen) Namespace zu importieren.

Das lief bis 2011 auch ganz gut, weil BOOST und die STL sich nicht in die Quere kamen.
Doch dann entstanden std::thread und std::mutex parallel zu boost:thread und boost::mutex.

Wer jetzt using namespace für beide Namensräume einsetzte bekam plötzlich Ambiguity Errors, weil der Compiler nicht richen kann, ob er jetzt std::ABC oder boost::ABC nutzen soll.

Heute in der Firma

Bei der Migration auf C++14 liefern mir 33% der Komponenten immer wieder solche Fehler.
Und heute hat es mir gereicht!

Ich machte also eine Suche nach using namespace std und löschte jede solche Zeile. using namespace boost blieb vorerst bestehen, da mit Ausnahme von std::string wesentlich mehr BOOST Nutzungen im Code waren, folglich sollte nur std explizit angegeben werden, wo es fehlte.

Meine Fresse, war das eine Fehleinschätzung, wieviele Typen plötzlich nicht mehr lauffähig waren!

Ich dachte mit ein bisschen Suchen+Ersetzen ist das in 30 Minuten erledigt.
Aber Fehlanzeige! Umzählige string, *stream, copy und min/max Token lagen kreuz und quere über alle möglichen Projekte verstreut.

Da hilft dann nichts anderes, als jede Zeile manuell zu fixen.

Fazit

Mir brummt immer noch der Schädel! Von allen Arbeiten ist das eine der dämlichsten, die man in der Programmierung machen kann … aber Hey, es hält nun hoffentlich lange.

Und sollte ich bei der nächsten Suche nach using namespace std noch etwas finden, dann mache ich den Kollegen ausfindig und tue im weh!

Also an alle lieben C++ Kollegen da draußen:

using namespace ist seit 1998 Tabu! Es hat nur in ganz wenigen Fällen (z.B.: swap) eine Existenzberechtigung, oder wenn man eigenen privaten Code von NUR EINEM Namespace aus schreibt. Ansonsten sind immer alle Typen korrekt zu addressieren, oder mit einem typedef nspace::some_type my_type; zu importieren. Zur Not kann man auch using nspace::some_type; gelten lassen.

Der wirkliche Skandal ist aber, dass using namespace gerne benutzt wird, um ein anderes Problem zu bekämpfen: Nämlich Namespaces, die unerträglich langatmig definiert sind.

Bitte führt keine namespace cool_app_code_assembly Bezeichnungen ein, die viel zu lange sind, um sie jedem Typen voran zu stellen.
Eine richtig kurze “coole” Abkürzung tut es auch, z.B.: namespace caca


Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!