const string * == const string * const



  • Nexus schrieb:

    Erklär mir bitte, wie man

    void Function (T x);
    

    hier x als Output-Parameter benutzen kann (falls T z.B. ein Klassentyp ist).

    Finde die Output-Parameter:

    void Function(int i, void *p, double x, const std::string &data, std::vector<int> &ret);
    

    Und jetzt nochmal:

    void Function(const int i, void *p, const double x, const std::string &data, std::vector<int> &ret);
    

    Welches ist lesbarer?



  • Wer Input- und Output-Parameter in beliebiger Reihenfolge mixt, ist komplett selbst schuld. Davon abgesehen, dass das Beispiel gekünstelt und die Variablennamen mies gewählt sind.


  • Mod

    Welches ist lesbarer?

    Erstes



  • nwp3 schrieb:

    Finde die Output-Parameter:

    void Function(int i, void *p, double x, const std::string &data, std::vector<int> &ret);
    

    Und jetzt nochmal:

    void Function(const int i, void *p, const double x, const std::string &data, std::vector<int> &ret);
    

    Welches ist lesbarer?

    Das hat viel damit zu tun, was man gewohnt ist und was üblicher ist.
    Und das ist definitiv das Erste!
    Ich würde beim Zweiten lange hängen bleiben, weil ich einen Fehler vermuten würde, weil irgendwas ausgedrückt wird/werden soll, was hier keinen Sinn macht.



  • Hmm, kann ich nicht nachvollziehen. Aber wenn ihr bei void foo(const int) echt ewig überlegt was der Sinn sein soll, dann ist es halt so. Vielleicht eine Gewöhnungs- bzw. Konsistenzsache.



  • Jockelx schrieb:

    Ich würde beim Zweiten lange hängen bleiben, weil ich einen Fehler vermuten würde, weil irgendwas ausgedrückt wird/werden soll, was hier keinen Sinn macht.

    Genau das. So gestaltete APIs machen auf mich direkt einen schlechten Eindruck, weil ich nicht weiss, ob was vergessen wurde oder die Entwickler gewisse C++-Prinzipien nicht verstanden haben.

    Schaut euch nur mal diverse etablierte C++-Bibliotheken an. Top-Level- const für Parameter benutzt nämlich niemand. Da 90% der Parameter reine Input-Parameter sind, müsste man extrem viele unnötige Schlüsselwörter hinschreiben, welche 1. die ganze Signatur weniger leserlich machen und 2. die sinnvollen Fälle für const (nämlich Zeiger/Referenz darauf) untergehen lassen, wodurch auch die Sensibilität für diese sinkt. Warum sollte man dem Aufrufer explizit mitteilen, dass der Parameter nicht geändert wird, obwohl das der Normalfall ist? Viel sinnvoller ist es, die Ausnahmefälle, also Output-Parameter kennzuzeichnen, was man mit & und * tut.

    Klar ist vieles Stilfrage, aber meines Erachtens sollte man -- zumindest wenn seinen Code teilt -- sich auch an gewisse etablierte Konventionen halten, die es für andere Leute einfacher machen, den Code zu verstehen. Dazu gehören unter anderem aussagekräftige Parameternamen, massvoller Einsatz von const und keine absichtlich verwirrende Reihenfolge -- also ziemlich genau nicht so wie im Beispiel von nwp3.



  • const kann man kaum oft genug verwenden, sofern es die Anwendbarkeit nicht einschränkt.

    Ein "const" in der Parameterliste ist nunmal deutlicher als wenn ich mir den "Fliegensch|*s" aus & und * ansehen muß. Und was die Reihenfolge von E/A-Parametern angeht, habe ich schon Funktionen gesehen, die die Ausgaben zuerst machen, und solche, die die Ausgaben zuletzt machen. Was mich wiederum zwingt, den "Fliegensch|*s" zu studieren, wenn kein "const" da steht.

    ... und noch eins:

    Ich schreibe meinen Code nicht für den Compiler -- dann könnte ich ja viel Zeit sparen, indem ich die Bezeichner durchnummeriere a la class C1 { }; ... class C2 { ...} ; int C3(const (sic) vector<C4> C5); ... -- sondern ich schreibe Code für mich bzw die übrigen Leser meines Quellcodes.

    Dem Compiler Arbeit zu sparen ist für mich kein Argument, solange die Alternative ist, den Code schneller erfaßbar zu gestalten.


  • Mod

    const kann man kaum oft genug verwenden, sofern es die Anwendbarkeit nicht einschränkt.

    Äh, Quatsch.

    Ein "const" in der Parameterliste ist nunmal deutlicher

    Nein, und wenn du deine Ansicht nicht änderst, wird mit dir keiner arbeiten wollen. Denn abgesehen von dir findet das so gut wie keiner lesbarer. Du ziehst an den Haaren irgendeinen Firlefanz herbei um dein längst widerlegtes Argument noch über Wasser zu halten.



  • großbuchstaben schrieb:

    const kann man kaum oft genug verwenden, sofern es die Anwendbarkeit nicht einschränkt.

    Ich nutze const zwar intensiv, aber niemals bei "By-Value"-Parametern. Diese werden kopiert, und daher bringt mir das const hier keinerlei Vorteil. Es mag "konsistenter" nicht aber unbedingt lesbarer sein wenn man diese mit const versieht. Zudem liefert das const an dieser Stelle auch weder eine Nutzinformation, noch einen Vorteil.



  • seit wann entscheiden wir denn demokratisch, was ich lesbarer zu finden habe ? 😃

    Aber egal. Wer ein wirklich gutes Gegenargument (außer "alle machen aber X ...") hat, kann sich ja melden.



  • großbuchstaben schrieb:

    Aber egal. Wer ein wirklich gutes Gegenargument (außer "alle machen aber X ...") hat, kann sich ja melden.

    Scheint leider nichts zu bringen.



  • Das beste Gegenargument ist wohl, dass es kein gutes Argument dafür gibt.



  • Es gibt drei Anwendungsfälle für by-Value:
    1. Kleine, trivial kopierbare Typen: Nur in diesem Fall greift die Debatte. Und das Argument, dass man das besser von Outputparametern unterscheiden kann, greift eh nur, wenn man Outputparameter hat (was bei mir fast nie auftritt). Das heißt wir diskutieren hier über einen minimalen Anwendungsfall. Und bei diesem minimalen Anwendungsfall kann man ruhig einmal genauer hingucken. Zusätzlich schränkt const den Einsatz ein, oft verändere ich diese Argumente (s. 2).
    2. Große, kostpielige kopierbare Typen bei denen man eine Kopie in der funktion verändern möchte: Wenn man eine Kopie innerhalb der Funktion braucht um sie lokal zu verändern. const macht dann da absolut keinen Sinn.
    3. in-Parameter: Ähnlich wie 2, die Kopie macht der Compiler beim Aufruf, um sie ins Ziel zu moven, dürfen sie nicht const sein.



  • Arcoth schrieb:

    Nein, und wenn du deine Ansicht nicht änderst, wird mit dir keiner arbeiten wollen. Denn abgesehen von dir findet das so gut wie keiner lesbarer. Du ziehst an den Haaren irgendeinen Firlefanz herbei um dein längst widerlegtes Argument noch über Wasser zu halten.

    lol

    "explizit ist besser als implizit" - und wenn ein einfaches "const" meine Intention als Programmierer ohne irgendwelche Nebenwirkungen verexplizifiziert, wird das von mir genutzt, basta.



  • Nathan schrieb:

    Es gibt drei Anwendungsfälle für by-Value:
    1. Kleine, trivial kopierbare Typen: [...]

    In jedem Fall, wo das Profiling einen zu vernachlässigenden Einfluß auf die Komplexität ergibt, entscheide ich mich für gewöhnlich für by-value. Warum für 0.1% mehr Performance den Code mit Sonderzeichen verunhübschen ? Optimieren kann man nötigenfalls immer noch.



  • großbuchstaben schrieb:

    Nathan schrieb:

    Es gibt drei Anwendungsfälle für by-Value:
    1. Kleine, trivial kopierbare Typen: [...]

    In jedem Fall, wo das Profiling einen zu vernachlässigenden Einfluß auf die Komplexität ergibt, entscheide ich mich für gewöhnlich für by-value. Warum für 0.1% mehr Performance den Code mit Sonderzeichen verunhübschen ? Optimieren kann man nötigenfalls immer noch.

    Lassen wir mal die Performance komplett außen vor:
    Im generischen Code kann man by-Value für pass-Parameter* nicht verwenden, da Objekte ja evtl. nicht kopierbar sind.
    Bei nicht kopierbaren Parametern kann man by-Value ebenfalls nicht verwenden.
    Es bleiben also nur noch nicht generische Funktionen mit kopierbaren Objekten übrig. Das heißt die Regel ist schon einmal nicht einheitlich. Alle nicht arithmetischen Typen als pass-Parameter by-Const-Reference, schon. Wir müssen also mehr nachdenken:
    Ist der Typ kopierbar? Oh, wo war die Datei doch gleich wo der war... Ah, hier. Kopierkonstruktor, Kopierkonstruktor, nein keiner deklariert, aber der hat eine basisklasse. Wo kommt die denn jetzt her? Ist die kopierbar? Nein, auch kein Kopierkonstruktor, die hat aber einen Member x. Ich glaub x, war kopierbar. *compilieren* Verdammt, x war nicht kopierbar.
    Im Gegensatz dazu:
    Ist der Typ char/int/float? Nein, pass-by-Value.
    Und wenn man jetzt die Performance dazu nimmt: Es macht vielleicht nicht viel aus. Aber a) ist das in High-Performance-Code evtl. schon zu viel (Stell dir ein Spiel vor, was in jedem Frame die komplette Liste aller Game-Objekte kopiert!) und b) schadet ein by-Reference nicht (Wenn du keine Sonderzeichen magst, programmier in BASIC!) und man kann es intuitiv ohne nachzudenken hinschreiben.

    *D.h. wird innerhalb der Funktion nicht verändert und auch nirgendwo hinkopiert.



  • großbuchstaben schrieb:

    basta

    Wozu noch diskutieren?
    Es ist alles gesagt: im Thread ist klar geworden, das eine klare Mehrheit die erste Variante für deutlich lesbarer hält.
    Jetzt kann der Leser selber entscheiden, ob er 1) lieber selber seinen Code gut lesen können möchte oder 2) andere ihn verstehen können sollen.
    (Wobei 2) natürlich idR nicht ausschließt, dass man den Code selber gut lesen kann, im Gegenteil)
    Fällt die Entscheidung auf 2), läßt man das const weg. Fertig!



  • Jockelx schrieb:

    Es ist alles gesagt: im Thread ist klar geworden, das eine klare Mehrheit die erste Variante für deutlich lesbarer hält.

    nur wird Wahrheit selten demokratisch entschieden.


  • Mod

    großbuchstaben schrieb:

    Jockelx schrieb:

    Es ist alles gesagt: im Thread ist klar geworden, das eine klare Mehrheit die erste Variante für deutlich lesbarer hält.

    nur wird Wahrheit selten demokratisch entschieden.

    Es geht hier darum, ob dein Code für andere lesbar ist. Und mit andere meine ich andere, nicht dich. Und wenn die Mehrheit der Anderen den Code nicht für lesbar hält, dann ist dein Code eben nicht lesbar - per Definition.



  • Wobei er eig. Recht hat, man kann seine Meinung nícht mit Lesbarkeit widerlegen.
    Was gut lesbar ist, ist eine Frage der Gewohnheit. Wären wir es alle gewohnt, const davor zu packen, könnten wir es auch problemlos lesen.
    Allein mit der Lesbarkeit zu argumentieren, reicht leider nicht.


Anmelden zum Antworten