Ansichten eines Informatikers

std::unique_ptr oder doch std::shared_pointer?

Hadmut
14.9.2023 1:43

Leserzuschrift zu C++.

C++: Indexprüfung, Informationsquellen für modernes C++

Sehr geehrter Herr Danisch,

meiner Kenntnis nach kann man in neu erstellten C++-Programmen gänzlich null-terminierte Strings vermeiden, indem man die STL verwendet, also z.B.

std::string s = “ab”.

Dann kann man mit

s.at(1)

anstelle des []-Operators auf das 2. Zeichen zugreifen, wobei ein Bounds-Checking durchgeführt wird. Ein Zugriff “hinter” der Stringlänge

s.at(2)

führt zu einer exception std::out_of_range.

Die Member function at gibt es seit dem C++-Standard von 1998, siehe https://en.cppreference.com/w/cpp/string/basic_string/at

Auch die Verwendung von Arrays sollte man zurückstellen und stattdessen std::vector verwenden. Auch für diesen Container ist at definiert, siehe

https://en.cppreference.com/w/cpp/container/vector/at.

Allgemein ist cppreference.com eine brauchbare Informationsquelle. Insbesondere wird da für jedes neue Sprach- bzw. STL-Element angegeben, mit welchem Standard dieses zum Sprachumfang hinzugefügt wurde.

Der Schöpfer von C++, Prof. Bjarne Stroustrup, hat schon erklärt, dass er er kein neues Buch zum Sprachstandard mehr schreiben wird, man muss also mit cppreference.com das Auslangen finden.

Eine weitere gute Informationsquelle scheinen mir auch die C++ Core Guidelines http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines zu sein. Dort werden manche Zusammenhänge etwas klarer.

Jedenfalls sollte man aufhören, C-Sprachelemente wie nullterminierte Strings, Arrays oder Raw-Pointers zu verwenden. Statt Raw-Pointers sollte man std::unique_ptr bzw. std::shared_pointer verwenden: https://en.cppreference.com/w/cpp/memory. Damit lassen sich eine ganze Menge trivialer Fehler wir z.B. Buffer-Overflows vermeiden.

Mit freundlichen Grüßen

Ja.

Das ist genau das Problem. Man kann. Und man sollte. Aber es ist nicht zwingend. Es ist nicht Teil der Sprache selbst, sondern nur der Laufzeitbibliothek. Und man sieht ja schon an der komplizierten Schreibweise, dass es ein ziemlicher Umstand ist. Und viele Leute benutzen dann eben doch die normalen C-Funktionen wie Pointer, Arrays, Null-terminierte Strings.

Ich hatte mal ein Buch über die Laufzeitumgebung von C++, in der genau das erläutert wurde. Aber ich glaube, ich habe es neulich mit ausgemistet, weil es völlig veraltet war. Ich kann mich aber noch gut erinnern, wie mich dieses Buch und die Laufzeitumgebung von C++ immer geärgert haben, weil es fürchterlich umständlich und unübersichtlich ist. Ein riesiges Buch für lächerlich wenige Funktionen.

Das machen dann in der Praxis eben auch viele nicht.

Besonders ärgert mich das, seit ich mal mit Ruby angefangen habe. Ruby hat zwar auch seine Probleme, und ist eine Interpreter- und keine Compilersprache, aber macht das alles sehr viel eleganter, knapper, lesbarer und sicher, obwohl, genau genommen, Arrays und dergleichen auch nicht Teil der Sprache, sondern der Laufzeit sind, nur bezüglich der Literale ( wie [1,2,3] ) in der Syntax verankert ist.

Das ganze Laufzeit-Ding ist bei C++ so nachträglich dazugeklatscht, und die Umständlichkeit zeigt, wie schwerfällig C++ sein kann.

Wie gesagt: Ich finde die Syntax und die Operatoren von Ruby weitaus besser und eleganter. Und das könnte man durchaus auch in einer Compiler-Sprache unterbringen.

Ich mache mir da aber wenig Hoffnung.

Wenn ich bedenke, dass zu den beliebtesten und meistverwendeten Sprachen Python und Go gehören, beide sprachlich-syntaktisch aber eher, naja, wenig Tiefe haben und in gewisser Weise die Position von Basic einnehmen, glaube ich nicht, dass das noch irgendwann mal richtig schön wird. Immerhin: Python und Go haben Indexprüfungen. Man kann da eine Menge Fehler schon nicht machen. Insofern sind sie auf jeden Fall ein Fortschritt.