Frage von ZeroclawX, 35

Unterscheidet sich der Zeigersyntax von C zu C++?

Die Frage ist eigentlich ganz einfach:

Gibt es einen Unterschied im Zeigersyntax von C und C++?

Und nochmal so nebenbei: Sind intelligente Zeiger SO viel nützlicher dass man diese eher benutzen sollte als normale Zeiger?

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von TeeTier, Community-Experte für programmieren, 8
Ja

Alles in allem: Jein. :)

Seit C99 kennt die Sprache das "restrict" Schlüsselwort um dem Compiler direkt zu sagen, dass es kein Aliasing gibt. Damit werden entsprechende C-Funktionen so schnell wie vorher schon ihr Fortran-Äquivalent.

(Vorher war genau DAS das Totschlagargument, warum Fortran-Programme schneller sind als C, was sich u. U. in einigen Algorithmen sogar DEUTLICH bemerkbar machte!)

Zeiger-Aliasing ist ein relativ kleines Thema, aber das würde hier den Rahmen sprengen, deshalb verlinke ich mal auf die Wikipedia:

https://en.wikipedia.org/wiki/Pointer\_aliasing#Aliasing\_and\_re-ordering

Um auf deine Frage zurück zu kommen: "restrict" gibt es bei C++ (leider) nicht, aaaaaaaber so ziemlich JEDER Compilerhersteller stellt dafür seine eigenen Schlüsselwörter bereit. Das ist zwar alles andere als schick, aber wenn man sich in die Makrohölle wagt, ist es trotzdem relativ portabel. :)

Auf der anderen Seite gibt es beim "register" Schlüsselwort auf Arrays (und damit indirekt auch Zeigern) fiese Unterschiede zwischen C und C++. (Bei C++ ist ein Zugriff über einen Index auf ein "register" Array Undefined-Behavior, bei C hingegen OK!)

"register" ist übrigens in C++ veraltet und wird in C++17 aus dem Standard fliegen, in C nicht. Da sich das auch auf Zeiger auswirkt, schreibe ich das hier mal dazu.

Dann gibt es ja noch die C++ Referenzen, die in C so nicht existieren. Da der erzeugte Maschinencode sehr ähnlich zu dem von Zeigern ist, erwähne ich das ebenfalls.

Außerdem gibt es (nur in C++!) LValue und RValue Referenzen, aber nur einen Typ Zeiger (sowohl in C, als auch C++).

Zu den Smart-Pointern haben die anderen ja schon genug geschrieben, also gehe ich da jetzt nicht näher drauf ein. :)

Ach so, und bei C wird Speicher natürlich mit einer der alloc()-Funktionen reserviert, und mit free() (früher auch cfree()) wieder freigegeben. Bei C++ nimmt man new und delete, sollte aber FAST IMMER darauf verzichten, und lieber irgendeine Form von Container (vector, deque, array, unique_ptr, ...) verwenden!

Vielen Einsteigern ist überhaupt nicht klar, wie "gefährlich" new und delete eigentlich sind. ><

Also es gibt einige Unterschiede zwischen C- und C++-Zeigern, allerdings ist die Syntax davon nur marginal und in Ausnahmefällen betroffen. Außer dem oben geschriebenen fallen mir zwar noch ein paar weitere Kleinigkeiten ein, aber ich wills jetzt auch nicht übertreiben.

Schönen Abend noch! :)

PS: Ich habe nur für "Ja" gestimmt, weil schon so viele andere vor mir für "Nein" gestimmt haben. Und da "restrict" ja auch zur Syntax gehört, liege ich damit vermutlich auch richtig. :)

Antwort
von SureYouCan, 12
Nein

Smart Pointer haben eine Menge Vorteile, ja. Sie bringen allerdings auch ein wenig Overhead mit.

Allerdings sehe ich es etwas anders als  NeoExacun. Es sollte eher die Regel als die Ausnahme das, dass du Smart-Pointer verwendest.

Wann du welchen verwenden solltest, kannst du in haufenweise Artikel nachlesen (-> einfach mal googlen)

Kommentar von TeeTier ,

Sehr gute Antwort, aber ich habe eine kleine Sache gefunden, an der ich mäkeln muss! :)

Smart Pointer haben eine Menge Vorteile, ja. Sie bringen allerdings auch ein wenig Overhead mit.

Nein, Smart Pointer bringen Null Overhead mit! Das ist ja gerade das geniale an den Dingern ... keinerlei negative Laufzeitauswirkungen.

(Voraussetzung ist ein halbwegs aktueller Compiler und C++11; Die veralteten auto_ptr davor hatten in der Tat oft Overhead.)

Wenn du das nicht glaubst, disassembliere doch mal kleines Testprogramm welches du mit mindestens -O1 kompilierst und vergleiche mal die Version mit rohem Speicher, unique_ptr, weak_ptr und shared_ptr.

Dass Shared-Pointer und Weak-Pointer einen Referenzzähler mitbringen kann man übrigens nicht als Overhead gelten lassen, da eine ähnliche Funktionalität in JEDEM Fall eine Art Zähler voraussetzt. Benötigt man das nicht, nimmt man sowieso Unique-Pointer.

Die Methoden der Smartpointer sind sowieso als inline, bzw. constexpr implementiert, also wird ein Aufruf über operator[] auf ein simples [] direkt auf den darunterliegenden Puffer optimiert: Kein Overhead!

(das gilt auch für [fast ausnahmslos] alle anderen Methoden)

Es sollte eher die Regel als die Ausnahme das, dass du Smart-Pointer verwendest.

Na wenigstens sind wir uns in diesem Punkt einig! ;)

Wenn ich ein "nacktes" new oder delete sehe, bekomme ich immer Ausschlag. Aber egal ... auf jeden Fall eine sehr gute Antwort! :)

Schönen Abend noch! :)

Kommentar von SureYouCan ,

Vielen Dank für die Korrektur! :).

Ich hatte mal irgendwo gelesen das smart pointer einen gewissen overhead mitbringen und habe es einfach mal so akzeptiert, ohne weiter darauf einzugehen (-> böser Fehler >.<).

Vielen Dank noch mal und auch dir einen schönen Abend! :)

Kommentar von TeeTier ,

Wie gesagt lagst du damit auch bis C++11 richtig! Damals waren erstens die Compiler noch nicht so "schlau" und die Implementierung von auto_ptr noch nicht so ausgereift wie bei den neueren Smart-Pointern.

Also alles kein Problem! Schönen Abend noch! :)

Antwort
von NeoExacun, 31
Nein

Nein.

Wenn du mit den Eigenschaften, die intelligente Zeiger bieten umgehen kannst und auf sie angewiesen bist, nutze sie. Wenn du sie nicht brauchst, oder nicht weißt wozu, dann kommst du wohl auch mit normalen Zeigern aus.

Kommentar von TeeTier ,

Wenn man nicht weiß, wie man Smart-Pointer einsetzt, sollte man sich hinsetzen und nachlesen. Es ist nichts Kompliziertes und sie bringen nur Vorteile, wobei sie gleichzeitig eine ganze Reihe an Nachteilen ausmerzen.

Und wer absolut faul ist, der merke sich einfach, dass er in Zukunft ...

Foo *foo = new Foo(123);
foo->doFancyThings(456);
delete foo;

... durch ..

auto foo = std::make_shared<Foo>(123);
foo->doFancyThings(456);

... ersetzen sollte, und damit gleich eine ganze Reihe Fliegen in Form von Sicherheitslücken und Bugs mit einer einzigen Klappe erschlagen hat.

Auch wenn man nur leicht mit C++ in Berührung kommt, so sind gerade Smart-Pointer vermutlich DER wichtigste Punkt, den man sich wirklich mal angucken sollte. :)

Keine passende Antwort gefunden?

Fragen Sie die Community