Wozu immer Zeiger?
-
Caligulaminus schrieb:
Warum ist das gut so?
Mir fällt spontan kein Grund ein, der dringend dagegen spricht.1. Sie lösen ein Problem, das niemand hat. In C++ gibt es vector.
2. Dafür würden sie komische Probleme bringen: Was soll zum Beispiel der Typ eines solchen Arrays sein und wann steht er fest? Auf diese Frage gibt es keine befriedigende Antwort und das in einer Sprache in der Typen dermaßen wichtig sind!
3. Und es führt Fehlerquellen in den Code ein, die man mit vector nicht hätte. Z.B.: Anforderung des Programms ändert sich, Array muss nun wirklich groß werden können? vector -> na und? VLA->Programm muss umgeschrieben werden.
4. Es macht eine Stackanalyse des Programms schwierig. Wie groß kann der Stack meines Programms maximal werden? Welche Rekursionstiefe kann ich mir erlauben? Alles nicht mehr beantwortbar.Und selbst wenn man zu den Punkten 2,3 und 4 auch Gegenargumente bringen kann, gilt immer noch 1. Und dann hätte man selbst bei den tollsten Gegenargumenten zu 2,3, und 4 immer noch ein Sprachmittel ohne Bedarf und mit potentiellen Problemen.
-
Dank für deine Zeit SeppJ,
1. Ich hatte VLA wahrscheinlich falsch interpretiert. Ich bezog mich darauf, ein Array mit einer Variablen als Größenangabe zu definieren.
int a[x]; // Wert von x ist zur Compilezeit nicht bekannt.Für Arrays mit veränderbarer Größe gibt's von mir keine Diskussion -> std::vector.
2. Steht ja fest. In meinem Beispiel: int.
3. Ich(als Compiler) würde sowas dann ja auch auf dem Heap anlegen. Alles andere wäre ja kreuzgefährlich.
4. Siehe 3.Im Prinzip läuft mein Kopfkino wohl auf sowas wie std::array hinaus (heißt das so?). Und damit wäre/ist die möglichkeit Arrays mit Variable als Größe auch überflüssig. Nur was spricht dagegen, soetwas als Sprachmittel einzuführen/zuzulassen. Wär' doch einfach einfacher.
-
@Caligulaminus: Du hast VLAs richtig interpretiert. Schon beim Gedanken an sizeof(a) aus deinem Beispiel packt mich das kalte Grauen. Und bei std::array<> muss die Größe des Arrays auch schon zur Compilezeit feststehen. Du könntest jetzt noch einen Zwischentyp entwerfen, der zwar eine feste Größe hat, aber diese erst zur Laufzeit übergeben bekommen hat, weil er im Gegensatz zu std::vector<> Speicher und evtl. etwas Laufzeit sparen könnte, da std::vector<> Speicher exponentiell allozieren muss, um logarithmische Komplexität gewährleisten zu können (was für ein Satz...). Ich halte das allerdings für nicht lohnenswert.
EDIT: Da VLAs auf dem Stack liegen, wäre das ja noch ein Zwischending. Wers unbedingt braucht, kann sich ja mit _alloca zumindest unter Linux was zusammenbasteln (oder so etwas ähnliches aka Compilermagik).@Noobfire: Wenn dich an Java und Delphi (die Sprache heißt übrigens Objekt Pascal) stört, dass man dauernd "mit Klassen rumhantieren" muss, dann hast du sie vermutlich noch nicht ganz verstanden. Und was die Intuitivität (gibt's das Wort?) angeht, würde ich lieber noch ein Weilchen abwarten. In C++ gibt es Dinge, die sind so unintuitiv, das kann man sich nur schwer vorstellen. Ich empfehle dir, ein gutes Buch zu lesen (auch über Java/Delphi/...), damit du die Zusammenhänge verstehst. In der Schule lernt man das Programmieren meistens sowieso nicht vernünftig (Erst klickibunti, und dann, wenn die Grundlagen fehlen, ist die Oberstufe zu Ende).
-
Caligulaminus schrieb:
1. Ich hatte VLA wahrscheinlich falsch interpretiert. Ich bezog mich darauf, ein Array mit einer Variablen als Größenangabe zu definieren.
Genau das sind VLAs. vector kann eben noch mehr.
2. Steht ja fest. In meinem Beispiel: int.
Das ist die schlechtestmögliche Antwort auf die Frage nach dem Typen. Welchen Typ hat denn deiner Meinung nach int[3]? Tipp: Es ist nicht int.

3. Ich(als Compiler) würde sowas dann ja auch auf dem Heap anlegen. Alles andere wäre ja kreuzgefährlich.
Wo ist dann der Sinn dieses Sprachmittels? Auf dem Heap habe ich vector und new.
4. Siehe 3.
Siehe 3.
Im Prinzip läuft mein Kopfkino wohl auf sowas wie std::array hinaus (heißt das so?).
std::array ist ein statisches Array dessen Größe zur Compilezeit feststehen muss. Es hat im Gegensatz zum normalen Array aber die von allen anderen Datentypen gewohnte Semantik.
Nur was spricht dagegen, soetwas als Sprachmittel einzuführen/zuzulassen. Wär' doch einfach einfacher.
Was wäre damit einfacher als mit vector? Siehe meine Einwände zu deinen Erwiederungen. Du sparst dir bloß 7 Zeichen (oder 12 mit std::) bei der Deklaration.
-
Hallo Sepp,
dann gab es wohl zwei Mißverständnisse.
Welchen Typ hat denn deiner Meinung nach int[3]? Tipp: Es ist nicht int.
Welchen sollte es schon haben?
int*, klassisches Array halt.Und daß std::arrays Größe zur Compilezeit feststehen muß war mir auch nicht bewußt.
Nun, wenn das die Einwände sind, sehe ich immer noch keinen dringenden Grund, solch ein Konstrukt auszuschließen(auch wenn der Vorteil eher minimal ist). In anderen Sprachen geht's doch auch.
Das Einzige 'Problem' wäre dann für mich noch die sizeof-Frage. Aber da finde ich den aktuellen Zustand in dem
sizeof alokal die Arraygröße(x sizeof typ) hergibt, in einer anderen Funktion dann aber nur die Zeigergröße verwirrender, als wenn man C-Arrays konsequent als Zeiger behandeln würde. Mit einer kleinen Änderund des Verhaltens von sizeof wäre dann ja alles klar.
Vielleicht sollte ich mich mal an die ISO wenden
.P.S. Ich habe überhaupt kein Problem mit dem Status quo, aber Neugier ist eine menschliche Eigenschaft, die es meiner Ansicht nach zu pflegen gilt.
Wie immer, Dank für Deine Zeit.
-
@Caligulaminus: Nein, ein int[3] hat den Typ int[3] - es ist aber in einen Zeiger konvertierbar. Diese Diskussion gab es schon öfters - warum ein Array kein Zeiger ist. Und wenn du sizeof() verändern willst, kannst du in C++ auch gleich ein neues Modulsystem einbauen. VLAs sind Dinge, die nur in 0.001% der Fälle nützlich wären - aus Effizienzgründen. Und die Gegenargumente - Inkonsistenz, Verwirrung, zusätzliche Arbeit für Kommitee/Compilerhersteller, noch mehr Anfängerverwirrung - sind viel gewichtiger.
Wer wirklich genau diese Mischung aus Effizienz und Dynamik braucht, soll sich an Inline-Assembler den Magen verderben.
-
Hast Du meinen
gesehen?
-
Caligulaminus schrieb:
Hast Du meinen
gesehen?Was meinst du? Mit wem redest du?
-
wxSkip schrieb:
Was meinst du?
Den ->
<-wxSkip schrieb:
Mit wem redest du?
Mit/zu Dir.
Ich bezog mich auf Deine (für meinen Geschmack zu ernste) Replik auf meine Überlegungen, den Sprachstandard nach meinen Sonderwünschen anpassen zu lassen, denen ich ja extra den rotnäsigen Zaunpfahl beistellte.
Die anderen Punkte waren für mich ja abgehandelt.
Ich denke nun, ich hätte etwas ausführlicher antworten sollen.Auch Dir gebührt mein herzlicher Dank für Deine Zeit/Anteilnahme.
Gruß
-
@Caligulaminus: Ok, den Smiley habe ich wohl in meinem Eifer überlesen. Aber auch wenn ich es nicht getan hätte, hätte ich gedacht, der Smiley bezöge sich nur auf den Teil mit der ISO und das andere halte ich trotzdem für eine dumme Idee, was ich nur hieb- und stichfest erläutern wollte.
P.S.: Du brauchst dich nicht immer so förmlich zu bedanken, ich bin selber Schuld, wenn ich im Forum Beiträge mit dem Thema "Zeiger" lese
.
-
Caligulaminus schrieb:
Im Prinzip läuft mein Kopfkino wohl auf sowas wie std::array hinaus (heißt das so?). Und damit wäre/ist die möglichkeit Arrays mit Variable als Größe auch überflüssig. Nur was spricht dagegen, soetwas als Sprachmittel einzuführen/zuzulassen.
Wenn du keinen zu alten C++ Compiler verwendest, gibts das schon:
std::tr1::array
-
Noobfire schrieb:
Ich frage mich nur, was denn der genaue Vorteil von Zeigern ist..
Klar, man kann so in einer Funktion eine überlieferte Variable sozusagen extern verändern..Mit Zeigern kann man Objekte, Variablen, etc.,verändern ohne erst davon eine Kopie erstellen zu müssen. Das spart Speicherplatz und ist schneller.
Wenn einer Funktion z.B. ein Objekt (z.B. bei einer Datenbank ein Datensatz mit zig Eigenschaften) als Wert übergeben werden soll, müßte im Prinzip das ganze Objekt in den Speicher der Funktion kopiert werden.
Falls diese Funktion dann sogar noch andere Funktionen aufruft, müßte das Objekt womöglich nochmal kopiert werden.
-
Zusammengefasst:
Zeiger braucht man für:
Bäume
verkettete Listen
Effizienz
Proxies
dynamische Allokation
Objekte auf dem Heap mit nicht-lokaler Lebenszeit
Zeiger oder Referenzen braucht man für:
Effizienz
Polymorphie
Referenzen braucht man für:
Syntaxzucker/Nachbildung eingebauter TypenEs gibt bestimmt noch mehr Dinge, aber das waren jetzt mal einige.
-
@wxSkip
Naja, brauchen tut man Zeiger eigentlich gar nicht
Für die von dir erwähnten Dinge sind sie aber praktisch.
-
hustbaer schrieb:
@wxSkip
Naja, brauchen tut man Zeiger eigentlich gar nicht
Für die von dir erwähnten Dinge sind sie aber praktisch.Sagen wir so, wahrscheinlich kann man viele Programme auch ohne Bäume, verkettete Listen etc. schreiben, aber das wird dann Laufzeitkritisch. Für dynamische Speicheranforderungen brauchst du Zeiger, auch wenn sie manchmal durch RAII-Objekte oder wie in funktionalen Sprachen ganz hinter der Implementierung versteckt werden.
Also kann man sagen, dass man Zeiger schon braucht. Sie müsssen aber nicht im Code auftauchen (z.B. auch Stack-Pointer o.ä.
).
-
Du könntest alles in großen globalen Arrays machen und Indizes statt Zeiger benutzen. Da kannst du auch wunderbare Bäume mit pflanzen

-
SeppJ schrieb:
Du könntest alles in großen globalen Arrays machen und Indizes statt Zeiger benutzen. Da kannst du auch wunderbare Bäume mit pflanzen

Super :p . Dann benutzt du halt ints als Zeiger. Und bei der Indizierung werden im Endeffekt doch wieder Zeiger addiert.
-
Argh. Verdammter Arrayzugriff
. Ja, da ist ein Zeiger in der Implementierung versteckt. Irgendwie bekommt man den bestimmt auch noch weg :p .
-
SeppJ schrieb:
Argh. Verdammter Arrayzugriff
. Ja, da ist ein Zeiger in der Implementierung versteckt. Irgendwie bekommt man den bestimmt auch noch weg :p .Und dann ist da immer noch der Stack-Pointer, damit du auf deine ints auch zugreifen kannst. :p
Damit du keine Zeiger brauchst, müsste jedes Programm mit den Registern auskommen. Und das wage ich zu bezweifeln.
-
wxSkip schrieb:
Und dann ist da immer noch der Stack-Pointer, damit du auf deine ints auch zugreifen kannst. :p
Ach, ich arbeite auf irgendeiner exotischen Maschine ohne Stack
. Das ist vom Standard erlaubt. 
Aber den Arrayzugriff ohne Pointer zu machen ist tatsächlich ganz schon tricky. Da fällt mir so spontan nichts als Ersatz ein.