Pointer vs. Referenz



  • *hust* OUT *hust*



  • verdammt, mein ich ja..

    edit: sagt mal... ist euch der Name des Threaderstellers aufgefallen? 🤡



  • JustAnotherNoob schrieb:

    bei fremden Code kannst du dich nicht drauf verlassen...

    Eben.
    Und was hilft mir eine Regel, auf die ich mich weder verlassen noch deren Verlässlichkeit ich überprüfen kann?
    ... und das alles für eine Information, für die es bereits ein standardisiertes, zuverlässiges und automatisiertes Verfahren gibt ("const") ?
    Dann besser keine Regel...

    Gruß,

    Simon2.



  • JustAnotherNoob schrieb:

    edit: sagt mal... ist euch der Name des Threaderstellers aufgefallen? 🤡

    Hehe. Ich denke, der Krieg im anderen Thread reicht, zumal sich die Argumente stark überschneiden. Trotzdem interessant, wie viele hier noch einmal ihre Position vertreten wollen... 😉



  • Simon2 schrieb:

    Und was hilft mir eine Regel, auf die ich mich weder verlassen noch deren Verlässlichkeit ich überprüfen kann?

    Das ist überall so.
    getFoo() ist für mich ein getter, aber für andere vielleicht die funktion zum initialisieren von Bar().

    Idiome verwendet man, weil es sinn macht sie zu verwenden - denn auf irgendwas müssen wir uns verlassen, wir müssen den anderen programmierern trauen. Sonst können wir ihren code nicht verwenden.

    ... und das alles für eine Information, für die es bereits ein standardisiertes, zuverlässiges und automatisiertes Verfahren gibt ("const") ?
    Dann besser keine Regel...

    Äh, der Punkt ist dass const zwar nett ist und const nimmt dir auch keiner weg - der Punkt ist, dass const nur im callee aufscheint aber nicht im caller.

    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.



  • Shade Of Mine schrieb:

    ...
    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.

    Ich weiß ... aber da hilft mir ja ein "&" anscheinend auch nicht unbedingt etwas...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Shade Of Mine schrieb:

    ...
    Und es geht um die kennzeichnung beim call... Und da hilft dir const garnichts.

    Ich weiß ... aber da hilft mir ja ein "&" anscheinend auch nicht unbedingt etwas...

    Gruß,

    Simon2.

    Es ist aber zumindest ein Indiz, das auf die Möglichkeit hinweist. Nach dem Motto "besser als gar nix"! Und in Verbindung mit eigenem Code vermischt sich dieses Indiz mit der eigenen Erinnerung oft zur Gewissheit.



  • _matze schrieb:

    ...Es ist aber zumindest ein Indiz, das auf die Möglichkeit hinweist. Nach dem Motto "besser als gar nix"! Und in Verbindung mit eigenem Code vermischt sich dieses Indiz mit der eigenen Erinnerung oft zur Gewissheit.

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Aber ich muss auch sagen: Die Qualität von Code hängt IMHO auch nicht zentral der Nicht-/Verwendung dieser Regel ab ... 😉

    Gruß,

    Simon2.



  • [quote="Simon2"]

    _matze schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß.
    Bei Übergabe eines Zeigers weiß ich, daß der Parameter nach Rückkehr verändert sein KANN.
    MIR erleichtert das Analyse und Fehlerrecherche.

    Wenn man Software im Team entwickelt und Teamintern eine solche Verfahrensweise einhält, ist das auch sehr hilfreich.

    Daß die Qualität von Code von dieser Verfahrensweise nicht zentral abhängt, denke ich auch.

    Ich würde das Ganze auch nicht als Regel bezeichnen, es ist halt eine Verfahrensweise, die manchen möglicherweise das Leben an der ein oder anderen Stelle etwas erleichtern kann - nur meine Meinung.



  • [quote="Belli"]

    Simon2 schrieb:

    _matze schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?
    - 0 erläubt?
    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)
    - irgendwelche "Speicherschweinereien" geplant?
    - auto-Objekt ("Stack") erlaubt?
    - ...

    Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß.
    Bei Übergabe eines Zeigers weiß ich, daß der Parameter nach Rückkehr verändert sein KANN.
    MIR erleichtert das Analyse und Fehlerrecherche.

    Wenn man Software im Team entwickelt und Teamintern eine solche Verfahrensweise einhält, ist das auch sehr hilfreich.

    Selbst wenn du es in deinem Team einhältst bringt es noch nicht wirklich viel, weil externe Libs es nicht so machen müssen außerdem bedeutet Pointer ja nicht zwangsläufig, dass das Object verändert wird und dann musst du doch wieder nachschauen.

    Und wirklich interessant ist das ganze auch nicht. Ich hab schon mit ner Menge fremden Code gearbeitet und debuggt, aber ob ein Objekt in einer Funktion verändert wird oder nicht, war eigentlich nie ein Problem.



  • Belli schrieb:

    ...Für mich geht es einfach und allein darum, daß ich bei Wartung, Pflege, Analyse von selbst geschriebenem Code beim Aufruf einer Funktion ohne Zeiger weiß, daß mein Parameter nach Rückkehr unverändert ist, OHNE daß ich mir die Funktionsdeklaration ansehen muß....

    "Es geht sich um Folgendes ...." 😉
    Ich möchte hier diskussionstechnisch mal unterscheiden zwischen 2 Situationen:
    A) Ich stolpere beim Maintance-Aufgabe über ein Stück Source der Form f(&x) . Da kommt mir die Idee "Aha! Diese Funktion könnte den Zustand von x verändern.
    Oder über ein Stück Code der Form std::string const s="Simon2"; f(s); . Da kommt mir die Idee "Aha! Diese Funktion wird diesen String wahrscheinlich nicht verändern."[/c].
    Diesen Gedankengang finde ich naheliegend und teile ihn auch.

    😎 Ich überlege mir eine neue Schnittstelle für meine Bibliothek und stehe vor der Frage "Wie soll die Parameterübergabe entworfen werden?".
    Dann kommt mir der Gedanke: "Da das ein update-Parameter werden soll, nehme ich einen Zeiger oder eine Refernzen. Damit der Benutzer (bzw. ein späterer 'Maintainer') direkt erkennen kann, dass es sich um einen update-Parameter handelt, entscheide ich mich für einen Zeiger."
    Diesen (kursiv hervorgehobenen) Gedankengang würde ich nicht teilen - aus den o.g. Gründen.

    Die Ausgangsfrage dieses Threads schien mir in Richtung 😎 zu gehen ... aber vielleicht ist das Alles auch nur ein schrecklicher Irrtum. 😉

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?

    Das kommt daher dass man immer sagt: Zeiger sind böse. Aber das sind sie nicht. Zeiger sind deine Freunde.

    - 0 erläubt?

    uninteressant beim code lesen. ist aber ein standard precondition fall. hat man bei referenzen und auch bei by value übergaben ebenfalls (in welchem zustand muss das objekt sein)

    - Polymorphie erwartet ?(ich weiß, geht auch mit Referenzen, da sind Zeiger aber doch noch verbreiteter)

    Hat rein garnichts mit Zeigern zu tun

    - irgendwelche "Speicherschweinereien" geplant?

    Nein.
    Du musst dem Code vertrauen - wenn du ihm nicht vertraust, dann warte ihn nicht.
    Speicherschweinereien kann ich mit Referenzen genauso machen.

    - auto-Objekt ("Stack") erlaubt?

    ja, immer.

    😎 Ich überlege mir eine neue Schnittstelle für meine Bibliothek und stehe vor der Frage "Wie soll die Parameterübergabe entworfen werden?".
    Dann kommt mir der Gedanke: "Da das ein update-Parameter werden soll, nehme ich einen Zeiger oder eine Refernzen. Damit der Benutzer (bzw. ein späterer 'Maintainer') direkt erkennen kann, dass es sich um einen update-Parameter handelt, entscheide ich mich für einen Zeiger."
    Diesen (kursiv hervorgehobenen) Gedankengang würde ich nicht teilen - aus den o.g. Gründen.

    Der Punkt ist nicht ob du es auch so machst sondern ob du verstehst warum es Sinn machen kann es so zu machen.
    Ich persönlich verwende nicht für OUT parameter Zeiger - aber ich verstehe den Gedankengang und sehe die Probleme die man damit löst.



  • Shade Of Mine schrieb:

    Simon2 schrieb:

    Ich muss gestehen: Ich finde es schlimmer als gar nichts, weil bei mir bei der Verwendung von Zeigerparametern immer sofort die Alarmglocken schrillen: Warum Zeiger?

    Das kommt daher dass man immer sagt: Zeiger sind böse. ...

    Nicht ganz.
    Sondern weil man
    a) 99% der Dinge ohne Zeiger machen kann und das
    b) in den allermeisten Fällen einfacher (nix mit -> oder 0-Prüfungen oder ...)

    Dafür haben Zeiger bestimmte Möglichkeiten, die sie für bestimmte Situationen ideal machen (deswegen sind sie auch meine Freunde).

    Shade Of Mine schrieb:

    ...
    Der Punkt ist nicht ob du es auch so machst sondern ob du verstehst warum es Sinn machen kann es so zu machen.
    Ich persönlich verwende nicht für OUT parameter Zeiger - aber ich verstehe den Gedankengang und sehe die Probleme die man damit löst.

    Moment: Nirgendwo habe ich gesagt, dass ich den Gedankengang nicht verstünde .... ich halte es nur nicht für die beste (und nicht einmal für eine erstrebenswerte) Herangehensweise an ein Problem ("Wie erkenne ich OUT-Parameter?").

    Gruß,

    Simon2.



  • Eine Möglichkeit, in/out/inout Parameter sicher zu erkennen, wären z.B. SAL Annotations. Ist aber MS-only, glaube ich. Außerdem leidet je nach Anwendung die Lesbarkeit doch stark...



  • Simon2 schrieb:

    Nicht ganz.
    Sondern weil man
    a) 99% der Dinge ohne Zeiger machen kann und das
    b) in den allermeisten Fällen einfacher (nix mit -> oder 0-Prüfungen oder ...)

    0 überprüfung ist ein schwaches argument. man muss nicht auf 0 prüfen

    referenzen und zeiger sind gleichwertig - zeiger bieten mehr möglichkeiten und man könnte referenzen aus c++ verbannen ohne dass es probleme geben würde.

    im prinzip existieren referenzen nur aus performance gründen...

    die meisten sprachen haben deshalb sogar garkeine referenzen sondern nur zeiger.

    und ich muss gestehen, wenn wir const& mal weglassen da diese ja nur aus performance gründen existieren - dann habe ich immer mehr zeiger als non-const referenzen in meinem code. und ich denke das wird den meisten leuten so gehen.

    deine argumentation ist also sehr schwach.
    warum sind zeiger schlechter als referenzen für out parameter?

    PS:
    und du hältst es also nicht als erstrebenswert out parameter zu kennzeichnen...?



  • Shade Of Mine schrieb:

    ... und ich denke das wird den meisten leuten so gehen...

    Nein, tut es nicht. Weder in unserer Firma (die mehrere tausend Mitarbeiter hat, von denen ein recht großer Anteil aus Softwareentwicklern besteht), noch, wenn man sich mal Publikationen von Leuten ansieht, die sich wirklich mit C++ auskennen. Es wurden sogar extra Referenz-Wrapper ersonnen, damit man noch weitgehender auf Zeiger verzichten kann.
    Das Referenzen nur aus Performance-Gründen eingeführt wurden, ist schlicht und ergreifend Blödsinn.
    Natürlich sind Referenzen nicht unbedingt notwendig. Genauso wenig sind Funktionen, Klassen oder erweiterte Kontrollstrukturen notwendig. man kann auch alles mit goto und if Programmieren.

    PS: Eigentlich wurde zu dem Thema schon alles gesagt. Das hier ist nur noch ein Flamewar...



  • Tachyon schrieb:

    Nein, tut es nicht. Weder in unserer Firma (die mehrere tausend Mitarbeiter hat, von denen ein recht großer Anteil aus Softwareentwicklern besteht), noch, wenn man sich mal Publikationen von Leuten ansieht, die sich wirklich mit C++ auskennen. Es wurden sogar extra Referenz-Wrapper ersonnen, damit man noch weitgehender auf Zeiger verzichten kann.

    Schau nochmal genauer hin.

    Wo verwendest du oder sonstwer non-const referenzen? Und dann zieh davon die out parameter ab...

    Was genau bleibt?

    Und zeig mir mal so einen referenz wrapper, klingt ja interessant...



  • war nicht an mich gerichtet was ich jetzt zitiere, aber ich geb trotzdem meinen senf dazu 🙂

    zeiger bieten mehr möglichkeiten und man könnte referenzen aus c++ verbannen ohne dass es probleme geben würde.

    nope. referenzen verhalten sich was "=" angeht komplett anders als zeiger. im zusammenspiel mit templates kann man damit dinge tun, die ohne zeiger nicht oder nur sehr umständlich möglich wären. mir fällt da z.B. boost::tie() ein.

    und ich muss gestehen, wenn wir const& mal weglassen da diese ja nur aus performance gründen existieren

    "const&" ist was performance angeht weder schneller noch langsamer als "&" -- was für performance-gründe meinst du? oder meinst du dass man "const&" statt "by value" verwendet? ja, klar, das stimmt, das macht man wegen der performance. oder auch mal gerne weil ein objekt nicht kopierbar ist. ist ja auch gut so.

    die meisten sprachen haben deshalb sogar garkeine referenzen sondern nur zeiger.

    die meisten sprachen haben referenzen, viele haben sogar *nur* referenzen, und z.t. sogar referenzen auf referenzen ("by ref" übergabe eines reference types unter C# z.B.). manche sprachen beschränken bloss referenzen auf parameterübergabe -- was daran besser sein soll weiss ich nicht. bzw. es ändert eben nix an der tatsache dass man beim call nicht sieht dass es "by ref" ist. in C# schon, da man es an der call-site explizit dazuschreiben muss. finde ich gut. würde uns in C++ aber das genick brechen - man denke bloss wieder an templates.

    dann habe ich immer mehr zeiger als non-const referenzen in meinem code.

    ich auch, wenn man smart pointer und "char const*" mitzählt. sonst nicht, da ich generell auch dann referenzen verwende wenn sie nicht const sind. wobei ich versuche diesen fall weitestgehend zu vermeiden, da ich output parameter nicht mag. weder mit zeigern noch mit referenzen.

    warum sind zeiger schlechter als referenzen für out parameter?

    PS:
    und du hältst es also nicht als erstrebenswert out parameter zu kennzeichnen...?

    doch, am besten macht man das indem man die funktionen die out parameter nehmen so nennt, dass jeder sofort weiss dass sie objekte modifizieren, und welche.

    Und zeig mir mal so einen referenz wrapper, klingt ja interessant...

    boost::ref<>



  • Shade Of Mine schrieb:

    im prinzip existieren referenzen nur aus performance gründen...

    nein. nichts geht mit referenzen performanter als mit zeigern. immer, wenn so optimierungen möglich sind, daß eine referenz nur ein zuätzlicher symboltabelleneibtrag auf ein anderes objekt ist, kann der entsprechenden zeiger auch wegoptimiert werden.
    ich vermute, referenzen mußten erfunden werden, um eine nette syntax bei manchen überladenen operatoren zu erlauben.
    ganz nebenbei ist es unfug, nur deswegen, weil sie für manche operatoren nötig sind, sie jetzt auf einmal überall zu nehmen, wo es erlaubt ist, aber da sind wir uns ja einig.



  • hustbaer schrieb:

    doch, am besten macht man das indem man die funktionen die out parameter nehmen so nennt, dass jeder sofort weiss dass sie objekte modifizieren, und welche.

    Du willst Funktionen so benennen, dass aus der Bezeichnung ersichtlich ist, ob und welche Parameter out (oder auch inout) sind? Bei mehreren Parametern wird das aber schwierig. 😉 Da halte ich SAL Annotations (oder was Selbstgebasteltes wie "#define OUT" und "#define INOUT") für sinnvoller.


Anmelden zum Antworten