Warum sind die Standardbibliotheken so unleserlich programmiert?



  • Wenn ich sowas sehe:

    _Pairib insert(const value_type& _Val)
    		{	// try to insert node with value _Val
    		_Nodeptr _Trynode = _Root();
    		_Nodeptr _Wherenode = _Myhead;
    		bool _Addleft = true;	// add to left of head if tree empty
    		while (!_Isnil(_Trynode))
    			{	// look for leaf to insert before (_Addleft) or after
    			_Wherenode = _Trynode;
    			_Addleft = _DEBUG_LT_PRED(this->comp,
    				this->_Kfn(_Val), _Key(_Trynode));
    			_Trynode = _Addleft ? _Left(_Trynode) : _Right(_Trynode);
    			}
    
    		if (this->_Multi)
    			return (_Pairib(_Insert(_Addleft, _Wherenode, _Val), true));
    		else
    			{	// insert only if unique
    			iterator _Where = _TREE_ITERATOR(_Wherenode);
    			if (!_Addleft)
    				;	// need to test if insert after is okay
    			else if (_Where == begin())
    				return (_Pairib(_Insert(true, _Wherenode, _Val), true));
    			else
    				--_Where;	// need to test if insert before is okay
    
    			if (_DEBUG_LT_PRED(this->comp,
    				_Key(_Where._Mynode()), this->_Kfn(_Val)))
    				return (_Pairib(_Insert(_Addleft, _Wherenode, _Val), true));
    			else
    				return (_Pairib(_Where, false));
    			}
    		}
    

    Ist das mit Absicht so komisch geschrieben?



  • Mal abgesehen von den Klammereinrückungen, die mir einen Tab zu weit hinten stehen und den Kommentaren, denen ich meistens gerne eine neue Zeile gönne, find ich es jetzt garnet so schlimm 😃



  • Die vielen _ machen sie damit es keine Namenskollisionen gibt. Ansonsten weiss ich auch nicht. Ja, sieht ziemlich mies aus.



  • Für lokale Variablen wäre das nicht nötig.
    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.


  • Mod

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.

    Was, wenn ich mich entscheide, alle normalen Namen mit hässlichen #defines zu belegen und dann eine Standardheader einbinde?



  • camper schrieb:

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.

    Was, wenn ich mich entscheide, alle normalen Namen mit hässlichen #defines zu belegen und dann eine Standardheader einbinde?

    Gutes Argument 🙂

    Was ich mich frage: wieso sind die ganzen Bezeichner so ultra-kurz? Wenn ich _Xran() in std::string lese, wird mir jedes mal ganz komisch zumute.
    Einzige Erklärung die mir einfällt (abgesehen von der dass P.J. Plauger nen seltsamen Humor haben könnte): kurz ist gut weil weniger RAM, weniger zu parsen -> schneller. Sollte aber eigentlich mittlerweile egal sein. Bzw. sobald man eine einzige Boost-Header einbindet, wird das vermutlich schon länger dauern, als wenn man alle Standard-Library Headers zusammen inkludiert.



  • hustbaer schrieb:

    Einzige Erklärung die mir einfällt (abgesehen von der dass P.J. Plauger nen seltsamen Humor haben könnte): kurz ist gut weil weniger RAM, weniger zu parsen -> schneller. Sollte aber eigentlich mittlerweile egal sein.

    Hmm. Wenn das mal der Grund war, dann könnte es jetzt auch einfach sein, dass es halt einfach immer noch so gemacht wird. Ist so weil war so und bleibt so.

    Die Einrückung finde ich auch unintuitiv, aber abgesehen davon gewöhnt man sich eigentlich recht schnell an die Benennung.

    Aber man müsste einen Verantwortlichen wirklich mal anschreiben..



  • volkard schrieb:

    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.

    Das wäre aber echt arsch...



  • camper schrieb:

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.

    Was, wenn ich mich entscheide, alle normalen Namen mit hässlichen #defines zu belegen und dann eine Standardheader einbinde?

    Ups, klar. Die Untersrtiche müssen sein.



  • volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.
    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.

    Was für einen Zweck hätte das denn?



  • Samyboy schrieb:

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.
    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.

    Was für einen Zweck hätte das denn?

    Schutz vor billiger Nachahmung. Wer den Code erstmal lesen kann der kann auch die Algorithmen selbst nachprogrammieren? 🙂

    MfG SideWinder



  • SideWinder schrieb:

    Samyboy schrieb:

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.
    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.

    Was für einen Zweck hätte das denn?

    Schutz vor billiger Nachahmung. Wer den Code erstmal lesen kann der kann auch die Algorithmen selbst nachprogrammieren? 🙂

    MfG SideWinder

    Naja, wieso wird es dann nicht ganz "ugly" geschrieben?

    z.B alles auf einer Linie, etc.



  • SideWinder schrieb:

    Samyboy schrieb:

    volkard schrieb:

    Für lokale Variablen wäre das nicht nötig.
    Ich vermute, das Zeugs wird ganz herkömmlich progammiert und dann durch einen Uglyfier gejagt.

    Was für einen Zweck hätte das denn?

    Schutz vor billiger Nachahmung. Wer den Code erstmal lesen kann der kann auch die Algorithmen selbst nachprogrammieren? 🙂

    Das bezweifle ich. 😉

    Wenn, dann hätten sie das richtig machen müssen, wie man das von gewissen C Programmen kennt. 😉



  • Samyboy schrieb:

    Naja, wieso wird es dann nicht ganz "ugly" geschrieben?
    z.B alles auf einer Linie, etc.

    Weil man's dann bemergen würde und Prettyprinter benutzen würde.



  • Es gibt Unternehmen (z.B. Dinkumware), die viel Manpower in die Entwicklung einer hochperformanten STL Implementation investieren. Durch die Template Programmierung ist es notwendig, viele Algorithmen und Techniken in den Header Dateien umzusetzen, die allerdings mit der STL Implementation weitergegen werden müssen. Man gibt quasi sein Know-How mit jeder Compiler Installation weiter. Der einzige Schutz vor Nachahmung besteht dann darin, den Code möglichst unverständlich zu machen, um es den Nachahmern so schwer wie möglich zu machen.
    Ich denke, dass volkard mit seiner Vermutung recht hat, der Entwicklercode wird vermutlich völlig anders aussehen und auch Kommentare enthalten; der Release Code wird wohl durch irgendeinen Obfuscator gejagt.



  • Aber wie ist das bei der Standardlibrary vom gcc, die steht unter der GPL, also darf sie nicht ausschließlch "obfuscated" ausgeliefert werden. Der Uglifier müsste in den Build/Installationsprozess eingebunden sein. Weiß da jemand was zu?



  • So unleserlich finde ich den Code gar nicht. Okay, der Stil ist vielleicht etwas gewöhnungsbedürftig (eingerückte {}-Blöcke, Klammern um return -Ausdrücke), aber immerhin kommentieren sie beim MSVC++ noch. Die Bezeichner aus dem Beispiel sind im Grossen und Ganzen auch eher verständlich.

    Obfuscator... klingt mir ehrlich gesagt etwas nach Verschwörungstheorie.



  • Warum sollten die Entwickler der Standardlibrary "Angst" um ihren Code haben?
    Macht doch keinen Sinn.



  • Nexus schrieb:

    So unleserlich finde ich den Code gar nicht. Okay, der Stil ist vielleicht etwas gewöhnungsbedürftig (eingerückte {}-Blöcke, Klammern um return -Ausdrücke), aber immerhin kommentieren sie beim MSVC++ noch. Die Bezeichner aus dem Beispiel sind im Grossen und Ganzen auch eher verständlich.

    Wenn bei uns in der Firma jmd. solche Bezeichner verwenden würde, dann wäre ein ernstes Gespräch fällig!
    Wenn ich in 10 Jahren als Programmierer eines gelernt habe, dann dass ein Bezeichner der "eh halbwegs verständlich ist, wenn man mal drüber nachdenkt" kaum besser ist, als ein total zufällig gewählter.

    Zeit will ich als Programmierer darauf verwenden das Programm als ganzes zu verstehen. Nicht darauf, die Bedeutung kryptischer Bezeichner zu erraten.



  • So unleserlich finde ich den Code gar nicht

    Würde ich auch sagen - ok, mag nicht als Musterbeispiel für verständlichen Code gelten, aber die Obfuscator-Theorie halte ich für übertrieben.
    Wenn man die ganzen Unterstriche entfernt und die Einrückung anpasst, sieht es schon viel besser aus:

    Pairib insert(const value_type& Val)
    {    // try to insert node with value _Val
        Nodeptr Trynode = Root();
        Nodeptr Wherenode = Myhead;
        bool Addleft = true;    // add to left of head if tree empty
        while (!Isnil(Trynode))
        {    // look for leaf to insert before (_Addleft) or after
            Wherenode = Trynode;
            Addleft = _DEBUG_LT_PRED(this->comp, 
                this->Kfn(Val), Key(Trynode));
            Trynode = Addleft ? Left(Trynode) : Right(Trynode);
        }
        if (this->Multi)
            return Pairib(Insert(Addleft, Wherenode, Val), true);
    


  • hustbaer schrieb:

    Wenn bei uns in der Firma jmd. solche Bezeichner verwenden würde, dann wäre ein ernstes Gespräch fällig!

    Das glaube ich dir gerne. Ich persönlich programmiere ja auch nicht so. Aber ich wollte eher darauf hinaus, dass man bei Bezeichnern wie _Nodeptr , _Root , _Insert noch halbwegs erahnen kann, was gemeint ist (okay, bei _Xran wirds dann schon schwieriger... :)). Ich weiss auch nicht, welchen Code-Richtlinien die MSVC++-Standardbibliotheksentwickler unterlagen, aber zu sagen der Code sei "obfuscated" scheint mir dann doch etwas übertrieben.


Anmelden zum Antworten