[C/C++] const auf integrale typen in einer Funktion sinnvoll?



  • ;fricky schrieb:

    hustbaer schrieb:

    Er muss den Code sowieso analysieren, da const_cast ja schliesslich erlaubt ist.

    muss er, aber er wird anders reagieren, wenn er 'const', 'const-wegcast' oder nichts davon findet. willst du sagen, 'const' hätte keinen einfluss auf den erzeuigten code, sondern ist lediglich auf der logischen ebene vorhanden?
    🙂

    ist mehr als nur logisch.

    int const size=100;
    char a[size];
    

    geht nicht ohne const.
    warum geht das eigentlich mit const? oder hat mich gcc nur zu sehr verwöhnt?

    double const PI=3.14;
    foo(PI);
    

    dringende empfehlung an den compiler, foo(3.14) zu schreiben und erlaubnis, keinen speicherplatz für PI anzulegen.



  • hustbaer schrieb:

    Er muss den Code sowieso analysieren, da const_cast ja schliesslich erlaubt ist. Nen? Eieieie...

    Der Compiler muss bei als const deklarierten Variablen nicht zwingend prüfen, ob jemals ein const_cast eingesetzt wird - deshalb ist das Verändern von Objekten, die ursprünglich const waren, ja auch undefiniert. Beispiel mit MSVC++:

    int main()
    {
    	const int a = 5;						// konstanter Ausdruck
    	const int b = (rand() >= 0) ? 5 : 1;	// kein konstanter Ausdruck
    
    	const_cast<int&>(a) = 42;
    	const_cast<int&>(b) = 42;
    
    	std::cout << a << std::endl;			// Ausgabe: 5
    	std::cout << b << std::endl;			// Ausgabe: 42
    }
    

    Ich bin auch nicht der Ansicht, dass nur static const -Member zur Optimierung beitragen können. Oder hab ich dich da völlig falsch verstanden?



  • Abgesehen von Semantik und Sicherheit: const braucht man (wie volkard angetönt hat) auch für konstante Ausdrücke, also Ausdrücke, deren Wert zur Kompilierzeit feststeht. Einige Sprachmittel in C++ erwarten integrale konstante Ausdrücke:

    const int ConstExpr = 3;
    
    // Enumeratoren
    enum Enum
    {
    	Enumerator = ConstExpr
    };
    
    // Bei der Definition initialisierte statische Konstanten
    class Class
    {
    	static const int Value = ConstExpr;
    };
    
    int main()
    {
    	// Template-Argumente
    	std::tr1::array<float, ConstExpr> a;
    
    	// Dimensionen von Arrays
    	int b[ConstExpr];
    
    	// Case-Konstanten
    	int c;
    	switch (c)
    	{
    		case ConstExpr: ;
    	}
    }
    


  • rüdiger schrieb:

    volkard schrieb:

    dort const halte ich für quatsch. ob ich später mal doch a ändern mag, ist mein geheimnis und hat in der schnittstelle nichts zu suchen.

    [...]
    Demnach kann man das Interface ohne const anbieten (da bringt das const ja nicht viel) und in der Implementierung dann const verwenden.

    hauptsache nicht im interface. Aus dem Grund nehme ich z.B. strings auch nur als const& und mache dann bei Bedarf selbst eine Kopie.

    Wer const als Schlüsselwort nicht verwenden will, schreibt es dann hoffentlich als Kommentar dazu. Ansonsten ist das nur nervig in einem großen Projekt, wo man mit viel Fremdcode zu tun hat.



  • OK, ihr habt Recht.
    Sorry.

    @Nexus: du hast mich richtig verstanden. Ich bin nur davon ausgegangen, dass die Compiler da viel konservativer sind. Also dass sie davon ausgehen, dass man auch const_cast auf (lokale) Variablen verwendet, die mit compile-time-konstanten Ausdrücken initialisiert wurden.

    Das von mir angenommen Kriterium "static const" ist also falsch. Vielmehr scheint es darum zu gehen, ob die Variable
    a) const ist und
    b) mit einem compile-time-konstanten Ausdruck initialisiert wird

    (In so einem Fall könnte man natürlich gleich auch static const schreiben, bloss es ist eben nicht - wie ich angenommen hatte - nötig, damit der Compiler "sich traut", mehr zu optimieren, als er sonst machen würde)

    @volkard:

    volkard schrieb:

    int const size=100;
    char a[size];
    

    geht nicht ohne const.
    warum geht das eigentlich mit const? oder hat mich gcc nur zu sehr verwöhnt?

    Wundert mich auch gerade dass das geht. VC9 frisst es aber auch.

    double const PI=3.14;
    foo(PI);
    

    dringende empfehlung an den compiler, foo(3.14) zu schreiben und erlaubnis, keinen speicherplatz für PI anzulegen.

    Das const in diesem speziellen Beispiel ist ziemlich* egal. Keiner zwingt den Compiler, Speicher für irgendwas anzufordern, solange das beobachtbare Verhalten stimmt. Und da zwischen der Definition von PI, und der Verwendung von PI nichts ist, was den Wert ändern könnte, kann der Compiler hier auch ohne const den Wert direkt ersetzen.

    *: "ziemlich" deswegen, weil ein guter Compiler hier auch ohne const "das richtige" macht. Natürlich kann es auch Compiler geben, die es ohne const nicht schnallen.



  • hustbaer schrieb:

    volkard schrieb:

    int const size=100;
    char a[size];
    

    geht nicht ohne const.
    warum geht das eigentlich mit const? oder hat mich gcc nur zu sehr verwöhnt?

    Wundert mich auch gerade dass das geht. VC9 frisst es aber auch.

    das liegt daran, dass in c++ ein 'const int size' einem '#define SIZE' sehr nahe kommt. in C89 geht sowas nicht, wohl aber in C99, wobei du da das 'const' sogar weglassen kannst.
    🙂



  • Shade Of Mine schrieb:

    Dieses Problem hat man in allen Sprachen wo es referenzen gibt.

    Interesanterweise gibt es das Kozept des const-correctness nur in C++. Alle anderen Sprachen kommen sehr gut ohne sowas aus. Stellt sich die Frage, ob man es wirklich braucht und ob es wirklich dem Programmierer hilft. Const ist wohl das neue Goto, man kann alles machen ohne es, aber es gibt jede Menge Programmierer, die auf Goto/Const schwoeren.



  • Aus meiner Sicht falsch. Man kann ohne auskommen. Man kann auch ohne Strom und fließend Wasser auskommen. Bequemer ist aber mit (Gründe kamen schon im Thread). Andere Sprachen haben auch keine Destruktoren und es gibt etliche Stellen an den ich die vermisse wenn ich in den Sprachen arbeiten muß. Also nur weils die Mehrheit anders macht muß es nicht besser sein.



  • DEvent schrieb:

    Shade Of Mine schrieb:

    Dieses Problem hat man in allen Sprachen wo es referenzen gibt.

    Interesanterweise gibt es das Kozept des const-correctness nur in C++. Alle anderen Sprachen kommen sehr gut ohne sowas aus. Stellt sich die Frage, ob man es wirklich braucht und ob es wirklich dem Programmierer hilft.

    Es hilft.
    Es hilft (begrenzt, aber nicht unwesentlich) gegen dumme Programmierer.
    Gegen die Programmierer, die sich nichts dabei denken würden in einem Getter irgendwas zu modifizieren, wenn der Compiler dabei nicht schreit. Die aber doch (gottseidank) zu feige und/oder zu blöd sind, einen const_cast dafür zu verwenden, um den Fehler zu "umschiffen".

    Ich habe schon in einigen Projekten Fehler gesucht. Das schlimmste war ein Projekt an dem > 5 Programmierer gearbeitet haben, wo keinerlei const verwendet wurde.
    Da gab es Dinge die kann man sich kaum vorstellen. So ala OpenFile(path); , und 5-10 Call-Stack Ebenen tiefer kommt man drauf, dass dieser Aufruf path modifiziert.

    Was andere Sparchen angeht: dort hilft man sich oft über "immutable" Klassen. An Stellen, wo diese total unnötig wären, wenn man const hätte.



  • Mir hilft es auch. Es hilft wesentlich gegen mich 😉 Damit weiss ich, was in der Funktion "input" ist und was man nicht verändern sollte.

    hustbaer schrieb:

    ...Da gab es Dinge die kann man sich kaum vorstellen. So ala OpenFile(path); , und 5-10 Call-Stack Ebenen tiefer kommt man drauf, dass dieser Aufruf path modifiziert...

    Ups, das mit path und mit modifizieren könnte gut ich gewesen sein...



  • DEvent schrieb:

    Shade Of Mine schrieb:

    Dieses Problem hat man in allen Sprachen wo es referenzen gibt.

    Interesanterweise gibt es das Kozept des const-correctness nur in C++. Alle anderen Sprachen kommen sehr gut ohne sowas aus.

    Lies meine Posts bitte.

    Ich habe gesagt const correctness ist in C++ genauso wichtig oder unwichtig wie in Java. Es ist ein Tool, mehr nicht.

    Stellt sich die Frage, ob man es wirklich braucht und ob es wirklich dem Programmierer hilft. Const ist wohl das neue Goto, man kann alles machen ohne es, aber es gibt jede Menge Programmierer, die auf Goto/Const schwoeren.

    Es gibt ja genug stimmen die auch ein const in Java fordern. Java hat zB das Konzept der immutable Klassen und final für primitive Typen. Statt T const& macht man in Java dann halt defensive Kopien.

    Wie du siehst hast du in Java und allen anderen Sprachen mit Referenzen das exakt selbe Problem. Ob const jetzt die beste Lösung ist sei mal dahingestellt - aber es ist eine gute Lösung.



  • DEvent schrieb:

    Interesanterweise gibt es das Kozept des const-correctness nur in C++.

    naja, aber so'nem konzept vertraut der erfinder von c++ wohl selbst nicht, denn sonst hätte wohl kaum einen 'const_cast' mitgeliefert.

    Shade Of Mine schrieb:

    Es gibt ja genug stimmen die auch ein const in Java fordern.

    bis vor 4...5 jahren etwa, aber die 'anti-const'-fraktion hat schliesslich gewonnen.
    🙂



  • ;fricky schrieb:

    DEvent schrieb:

    Interesanterweise gibt es das Kozept des const-correctness nur in C++.

    naja, aber so'nem konzept vertraut der erfinder von c++ wohl selbst nicht, denn sonst hätte wohl kaum einen 'const_cast' mitgeliefert.

    Dann traut wohl Niemand dem Typen Konzept, denn warum sonst gibt es type-casts?

    Shade Of Mine schrieb:

    Es gibt ja genug stimmen die auch ein const in Java fordern.

    bis vor 4...5 jahren etwa, aber die 'anti-const'-fraktion hat schliesslich gewonnen.
    🙂

    ich sage nicht dass const in java eine gute idee ist, nur dass man es sich ernsthaft überlegt hat.



  • Shade Of Mine schrieb:

    ;fricky schrieb:

    DEvent schrieb:

    Interesanterweise gibt es das Kozept des const-correctness nur in C++.

    naja, aber so'nem konzept vertraut der erfinder von c++ wohl selbst nicht, denn sonst hätte wohl kaum einen 'const_cast' mitgeliefert.

    Dann traut wohl Niemand dem Typen Konzept, denn warum sonst gibt es type-casts?

    nicht das typen-konzept an sich, sondern das 'irgendwas-correctness'-konzept ist zu unhandlich. niemand spricht von char- float- oder long-correctness, weil's klar ist, dass gewisse sinnvolle typkonvertierungen möglich sein müssen. und genauso isses mit 'const' und dem const-cast. mit const-correctness macht man sich nur unnötig das leben schwer, ohne gross was zu gewinnen. auch ein nicht const-korrektes programm kann sonst korrekt sein.
    btw, wieso hört man eigentlich nichts von 'static'- oder 'volatile'-correctness?
    🙂



  • ;fricky schrieb:

    mit const-correctness macht man sich nur unnötig das leben schwer, ohne gross was zu gewinnen. auch ein nicht const-korrektes programm kann sonst korrekt sein.

    du hast noch nie im team programmiert oder sonst großartig mit fremdcode zu tun gehabt, oder? die welt ist größer als die eigenen 2000 zeilen wo man immer schön den durchblick hat.

    btw, wieso hört man eigentlich nichts von 'static'- oder 'volatile'-correctness?

    weil das überhaupt keinen sinn macht. Weißt du was die wörter bedeuten?!



  • DrGreenthumb schrieb:

    du hast noch nie im team programmiert oder sonst großartig mit fremdcode zu tun gehabt, oder?

    doch, beides.

    DrGreenthumb schrieb:

    Weißt du was die wörter bedeuten?!

    in C? schau mal hier:
    http://en.wikipedia.org/wiki/Static_variable
    http://en.wikipedia.org/wiki/Volatile_variable
    🙂



  • ;fricky schrieb:

    DrGreenthumb schrieb:

    Weißt du was die wörter bedeuten?!

    in C? schau mal hier:
    http://en.wikipedia.org/wiki/Static_variable
    http://en.wikipedia.org/wiki/Volatile_variable
    🙂

    das "?!" sollte andeuten, dass ich dir frecherweise unterstelle, dass DU es nicht weißt.

    Schonmal versucht static oder volatile wegzucasten? Die Eigenschaften sind überhaupt nicht mit const vergleichbar.



  • DrGreenthumb schrieb:

    Schonmal versucht static oder volatile wegzucasten? Die Eigenschaften sind überhaupt nicht mit const vergleichbar.

    Ach nein? Dann ist es also Zufall, dass man von CV-Qualifizierern spricht, wenn man const und volatile meint?

    static ist hingegen eine Speicherklasse und hat wirklich nichts damit zu tun.



  • @DrGreenthumb:
    Doch, volatile verhält sich *exakt so wie const *.
    static natürlich nicht, das ist klar.

    EDIT: es heisst auch nicht umsonst "cv-qualified" 🙂

    Und von volatile hört man in dem Zusammenhang nichts, weil volatile einfach keine sinnvolle Anwendung hat.

    @fricky:

    nicht das typen-konzept an sich, sondern das 'irgendwas-correctness'-konzept ist zu unhandlich.

    Sehe ich genau andersrum: unpraktisch finde ich, dass C++ viel zu wenig solche Checks ermöglicht.

    niemand spricht von char- float- oder long-correctness, weil's klar ist, dass gewisse sinnvolle typkonvertierungen möglich sein müssen

    Versuch mal in C# eine Konvertierung von int nach short zu machen. Oder von int nach unsigned int.
    Und darüber sprechen auch genug Leute, bzw. schreiben.
    Ich kann also nicht ganz nachvollziehen was du meinst.

    Falls du meinst es spricht keiner darüber im Zusammenhang mit C++: das liegt vermutlich daran, dass es in C++ eben nicht geht, da C++ solche Konvertierungen nunmal implizit erlaubt.



  • DrGreenthumb schrieb:

    das "?!" sollte andeuten, dass ich dir frecherweise unterstelle, dass DU es nicht weißt.

    dann weiss ich's spätestens jetzt, brauche ja nur die verlinkten seiten zu lesen.

    DrGreenthumb schrieb:

    Schonmal versucht static oder volatile wegzucasten? Die Eigenschaften sind überhaupt nicht mit const vergleichbar.

    naja, zumindest 'volatile' ist ein qualifizierer ähnlich wie 'const', da könnte doch auch jemand auf idee kommen, 'volatile-correctness' zu erfinden.
    🙂


Anmelden zum Antworten