[C/C++] const auf integrale typen in einer Funktion sinnvoll?
-
Ich will aber nicht, dass jemand diese Parameter ändert, weil wenn er es tut, dann kann er dabei etwas falsch machen, es sei denn, er ist wirklich gut, aber wer kann denn schon von sich behaupten, er wäre wirklich gut
-
Don06 schrieb:
Mit const_cast kann man auch volatile wegcasten. const_cast ist ein schlechter Name. Damit kann man cv-Qualifizierungen umwandeln.
wenn ich c++ proggen müsste, würde ich sowieso nur C-casts verwenden, ausser wenn ich in einer vererbungshierarchie downcasten will. sowas geht mit C-casts ja nicht.
-
;fricky schrieb:
Don06 schrieb:
Mit const_cast kann man auch volatile wegcasten. const_cast ist ein schlechter Name. Damit kann man cv-Qualifizierungen umwandeln.
wenn ich c++ proggen müsste, würde ich sowieso nur C-casts verwenden, ausser wenn ich in einer vererbungshierarchie downcasten will. sowas geht mit C-casts ja nicht.
ja fricky.
weil du ein uneinsichtiger koffer bist.wegen leuten wie dir gibt es so viel furchtbar miesen C++ code.
-
hustbaer schrieb:
;fricky schrieb:
Don06 schrieb:
Mit const_cast kann man auch volatile wegcasten. const_cast ist ein schlechter Name. Damit kann man cv-Qualifizierungen umwandeln.
wenn ich c++ proggen müsste, würde ich sowieso nur C-casts verwenden, ausser wenn ich in einer vererbungshierarchie downcasten will. sowas geht mit C-casts ja nicht.
ja fricky.
weil du ein uneinsichtiger koffer bist.
wegen leuten wie dir gibt es so viel furchtbar miesen C++ code.ach nö. schlechten c++ code gibts durch diese vielen 'zu-kompliziert-denker'. das sind bestimmt 2/3 aller c++ anwender.
hier ein beispiel von heute: http://www.c-plusplus.net/forum/viewtopic-var-t-is-250597.html
ein c-cast erschlägt alle c++ casts, nur nicht den polymorphen 'dynamic_cast'. das steht sogar, glaub ich, im c++ standard drin. es gibt eine feste reihenfolge, in der die anderen casts durchprobiert werden. warum sollte man diese automatik nicht nutzen?
-
;fricky schrieb:
ach nö. schlechten c++ code gibts durch diese vielen 'zu-kompliziert-denker'. das sind bestimmt 2/3 aller c++ anwender.
hier ein beispiel von heute: http://www.c-plusplus.net/forum/viewtopic-var-t-is-250597.htmljajablabla
ein c-cast erschlägt alle c++ casts, nur nicht den polymorphen 'dynamic_cast'. das steht sogar, glaub ich, im c++ standard drin. es gibt eine feste reihenfolge, in der die anderen casts durchprobiert werden.
dynamic_cast überhaupt nicht. davon abgesehen richtig. und?
warum sollte man diese automatik nicht nutzen?
weil man damit unabsichtlich einen const_cast machen kann (ohne dass der compiler ne warnung gibt).
weil man damit unabsichtlich einen reinterpret_cast machen kann (ohne dass der compiler ne warnung gibt).
weil man sie nicht per "find in files" auffinden kann.
weil sie weniger "sichtbar" und weniger aussagekräftig sind (man braucht länger, um draufzukommen "wohin" eigentlich gecastet wird, und warum).
-
hustbaer schrieb:
weil man damit unabsichtlich einen const_cast machen kann (ohne dass der compiler ne warnung gibt).
weil man damit unabsichtlich einen reinterpret_cast machen kann (ohne dass der compiler ne warnung gibt).
weil sie weniger "sichtbar" und weniger aussagekräftig sind (man braucht länger, um draufzukommen "wohin" eigentlich gecastet wird, und warum).das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
hustbaer schrieb:
weil man sie nicht per "find in files" auffinden kann.
hier: http://hz211.blogspot.com/2006/03/regular-expression-to-find-c-style.html
aber mal ehrlich, nach casts zu suchen kommt ja wohl sehr selten vor.
-
;fricky schrieb:
hustbaer schrieb:
weil man damit unabsichtlich einen const_cast machen kann (ohne dass der compiler ne warnung gibt).
weil man damit unabsichtlich einen reinterpret_cast machen kann (ohne dass der compiler ne warnung gibt).
weil sie weniger "sichtbar" und weniger aussagekräftig sind (man braucht länger, um draufzukommen "wohin" eigentlich gecastet wird, und warum).das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
ach ne, klar.
class Base {}; class Derived : public Base {}; class SomethineCompletelyDifferent {}; void foo(Derived* p){} void foo(SomethineComplep){} void test1(Base const* p) { foo((Derived*) p); // const_cast - OOPS! } void test2(Base* p) { foo((SomethineCompletelyDifferent*) p); // reinterpret_cast - OOPS! } class X; class Y; void register_xy(X* p) {} void register_xy(Y* p) {} void unregister_xy(X* p) {} void unregister_xy(Y* p) {} template <class DERIVED> class curiously_recurring_template_pattern { public: curiously_recurring_template_pattern() { register_xy((DERIVED*) this); } ~curiously_recurring_template_pattern() { unregister_xy((DERIVED*) this); } }; class Y : public curiously_recurring_template_pattern<Y> // OK { }; // und nu ein kleiner copy & pase fehler... // (sollte curiously_recurring_template_pattern<X> heissen, aber das hat wohl wer übersehen) class X : public curiously_recurring_template_pattern<Y> // OOOOOPS! C-style cast wird zu reinterpret_cast in // curiously_recurring_template_pattern's ctor und dtor... { }; void stupid_function(Base* p) { } void stupid_function(Derived* p) { } template <class T> void stupid_function2(T* t) { // ... // wir wollen immer den Base* overload, daher casten wir stupid_function((Base*) t); } void test4() { Derived const* p = new Derived(); stupid_function2(p); // const_cast in stupid_function2 - OOPS! }
hustbaer schrieb:
weil man sie nicht per "find in files" auffinden kann.
hier: http://hz211.blogspot.com/2006/03/regular-expression-to-find-c-style.html
aber mal ehrlich, nach casts zu suchen kommt ja wohl sehr selten vor.ja klar, man will sich ja auch nie vergewissern dass keiner irgendwo nen const_cast macht (und dann böses damit anstellt). kommt auch gerade beim fehler-suchen nie vor.
p.S.: die regex ist "schön", ja, danke. ist aber auch sehr "einfach", ne?
vielleicht sollte ich da gleich morgen nen check in unseren pre-commit hook hängen.
-
DEvent schrieb:
Oder man nimmt einfach eine vernueftige Sprache fuer das Problem, anstelle kostbare Entwicklungszeit mit dem Erstellen, der Kontrolle und der Durchsetzung idiotischen Regeln zu verplempern.
Noch einfacher wäre es, beim Programmieren selbst und nicht nur bei der Wahl der Sprache die Vernunft einzusetzen.
abc.w schrieb:
Ich will aber nicht, dass jemand diese Parameter ändert, weil wenn er es tut, dann kann er dabei etwas falsch machen, es sei denn, er ist wirklich gut, aber wer kann denn schon von sich behaupten, er wäre wirklich gut
Tatsache ist aber, dass das Top-Level-
const
nichts in der Schnittstelle zu suchen hat, weil es keine relevante Information beinhaltet.
-
hustbaer schrieb:
hier: http://hz211.blogspot.com/2006/03/regular-expression-to-find-c-style.html
aber mal ehrlich, nach casts zu suchen kommt ja wohl sehr selten vor.ja klar, man will sich ja auch nie vergewissern dass keiner irgendwo nen const_cast macht (und dann böses damit anstellt). kommt auch gerade beim fehler-suchen nie vor.
ich hab' gerade überlegt, wann ich mal code nach casts durchsucht habe, aber mir ist echt nichts eingefallen. kann natürlich sein, dass suchen nach casts unter c++ üblich ist (vielleicht weil's verschiedene casts gibt, die man verwechseln kann?), aber das entzieht sich meiner kenntnis.
zu dem code-beispiel: falls du zeigen wolltest, dass man absichtlich fehler einbauen kann, so isses dir gelungen. nur, mit c++-cast hättest du ebenso fehler produzieren können. man muss wissen was man tut. ich sehe nicht, dass c++ casts einem das abnehmen.
-
abc.w schrieb:
Ich will aber nicht, dass jemand diese Parameter ändert, weil wenn er es tut, dann kann er dabei etwas falsch machen, es sei denn, er ist wirklich gut, aber wer kann denn schon von sich behaupten, er wäre wirklich gut
Dann kopiert er einfach. Das können auch schlechte Programmierer. Du hast also nichts gewonnen. Das Interface ist schwerer verständlich, der Profi ist genervt, und der Anfänger macht den selben Müll wie sonst auch immer.
@ Basher. oder Basher_ist_nicht_Bashar (Wettschulden sind Ehrenschulden)
das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
Aber Interfaces ändern sich. Der cast macht aber trotzdem weiterhin, was er immer macht. Dann geht etwas kaputt und niemand merkt es, weil der Compiler bevormundet wird.
-
otze schrieb:
das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
Aber Interfaces ändern sich. Der cast macht aber trotzdem weiterhin, was er immer macht. Dann geht etwas kaputt und niemand merkt es, weil der Compiler bevormundet wird.
^^endlich ein gutes argument gegen c-casts, dazu fällt mir keine lästerei mehr ein. static- und dynamic-casts scheitern, wenn die typen nicht mehr zueinander passen, ne?
das klappt natürlich nicht, wenn einer reinterpret-cast verwendet hat.
-
;fricky schrieb:
otze schrieb:
das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
Aber Interfaces ändern sich. Der cast macht aber trotzdem weiterhin, was er immer macht. Dann geht etwas kaputt und niemand merkt es, weil der Compiler bevormundet wird.
^^endlich ein gutes argument gegen c-casts, dazu fällt mir keine lästerei mehr ein. static- und dynamic-casts scheitern, wenn die typen nicht mehr zueinander passen, ne?
das klappt natürlich nicht, wenn einer reinterpret-cast verwendet hat.
fricky, säufst du?
das ist genau das, was ich geschrieben habe.
oh mann...ach, vergessen. ich hab dich nicht mit der nase drauf gestossen. aber hätte ich es, hättest du es genauso überlesen bzw. ignoriert, wie du es mit allem machst was ich schreibe.
p.S.: vielleicht kommt es auch nur daher, dass du nie C++ programmierst. dann solltest du dich aber vielleicht auch bei C++ themen raushalten.
-
;fricky schrieb:
hustbaer schrieb:
hier: http://hz211.blogspot.com/2006/03/regular-expression-to-find-c-style.html
aber mal ehrlich, nach casts zu suchen kommt ja wohl sehr selten vor.ja klar, man will sich ja auch nie vergewissern dass keiner irgendwo nen const_cast macht (und dann böses damit anstellt). kommt auch gerade beim fehler-suchen nie vor.
ich hab' gerade überlegt, wann ich mal code nach casts durchsucht habe, aber mir ist echt nichts eingefallen.
;fricky schrieb:
DrGreenthumb schrieb:
machst du einfach immer erstmal eine Kopie von deinem Buffer bevor du eine Fremdfunktion aufrufst? Oder verfolgst du den Weg den der Buffer so beschreitet?
ich vergewissere mich zumindest, ob meine daten verändert werden können oder nicht. ein 'const' im funktionskopf ist schon mal ein guter hinweis, aber keine garantie.
hm.
was glaubst du wohl, wieso ich jemals auf die idee kommen könnte, nach casts zu suchen. hmmmmmm.;fricky schrieb:
man muss wissen was man tut. ich sehe nicht, dass c++ casts einem das abnehmen.
sie decken *manche* fehler auf. was ist besser: manche fehler aufdecken, oder keine fehler aufdecken?
keine natürlich, denn man muss ja wissen was man tut!
-
hustbaer schrieb:
;fricky schrieb:
otze schrieb:
das stimmt doch garnicht. du schreibst in die klammern rein, wohin gecastet werden soll. da ist nichts unbeabsichtigt und auch nicht schlecht sichtbar.
Aber Interfaces ändern sich. Der cast macht aber trotzdem weiterhin, was er immer macht. Dann geht etwas kaputt und niemand merkt es, weil der Compiler bevormundet wird.
^^endlich ein gutes argument gegen c-casts, dazu fällt mir keine lästerei mehr ein. static- und dynamic-casts scheitern, wenn die typen nicht mehr zueinander passen, ne?
das klappt natürlich nicht, wenn einer reinterpret-cast verwendet hat.
fricky, säufst du?
das ist genau das, was ich geschrieben habe.nö, du schreibst immer, dass diese dinge existieren, um den programmierer vor sich selbst zu schützen (und wenn das nicht reicht, dann müssen zusätzliche regeln her). für diese haltung hab ich kein verständnis. ich bin eher ein anhänger des 'spirit of C': http://www.cnblogs.com/WarrenTang/archive/2008/03/16/1108873.html
wir haben hier gerade mal ein beispiel, bei dem diese unterschiedlichen c++ casts (richtige angewendet) was bringen. demgegenüber steht die verwechslungsgefahr und das bedürfnis, den code nach casts durchsuchen zu müssen.hustbaer schrieb:
p.S.: vielleicht kommt es auch nur daher, dass du nie C++ programmierst. dann solltest du dich aber vielleicht auch bei C++ themen raushalten.
'const', um das es hier geht, betrifft auch C. ausserdem bin ich sehr glücklich darüber, nicht in C++ programmieren zu müssen. *fg*
hustbaer schrieb:
;fricky schrieb:
man muss wissen was man tut. ich sehe nicht, dass c++ casts einem das abnehmen.
sie decken *manche* fehler auf. was ist besser: manche fehler aufdecken, oder keine fehler aufdecken?
sie decken eine mögliche fehlerquelle auf, führen aber zwei oder drei neue ein. dieser effekt ist typisch für C++.
-
Ich habe gemeint, wenn du etwas als private/protected/usw deklarierst, dann bleibt es auch dabei.
Nein, das ist nicht unbedingt der Fall. Guck mal using an.
-
;fricky schrieb:
sie decken eine mögliche fehlerquelle auf, führen aber zwei oder drei neue ein. dieser effekt ist typisch für C++.
Jein. Sie zwingen den Programmierer dazu, darüber nachzudenken, was er eigentlich will. Er muss zwischen 4 casts wählen, die jeweils andere Hinweise geben:
const_cast wirft die Frage auf, ob ich das Objekt wirklich entconsten muss - wahrscheinlich ist es doch keine so gute Idee, darauf jetzt rumzuschreiben. Andererseits ist entconsten notwendig, wenn ich eine Klasse verwende, die const correctness nicht kennt(übrigens ist das der Grund, weswegen const_cast eingeführt wurde. Das Feature war schließlich nicht in Version 1 von C++ enthalten, deswegen gab es bereits eine Menge Code, die von dem Feature beeinflusst wurden. Und den musste man kompatibel machen).
reinterpret_cast lässt die Alarmglocken schrillen: was du da machst, ist potentiell Fehleranfällig und nicht portabel. Denk noch einmal drüber nach, was da passiert. Brauchst du es wirklich?
dynamic_cast sagt: okay, teste mal, ob das Ding diese Basisklasse ist. funktioniert natürlich nur bei polymorphen Typen, und darauf passt der Compiler auf. Also keine Gefahr. Oder doch: Auf 0 testen, oder Exception fangen. Nur für den Fall.
static_cast keine Gefahr, was da passiert schaltet normalerweise nur eine Warnung aus. Wenn was schief geht, meckert der Compiler rum.
C-Cast: ??? Potentiell gefährlich. Effekt nicht abschätzbar, ohne alles drum herum zu kennen.
-
fricky, glaub was du willst.
ich kann dich echt nicht mehr ernst nehmen.
geh uns spiel mit deinem C compiler.
-
Don06 schrieb:
Mit const_cast kann man auch volatile wegcasten. const_cast ist ein schlechter Name. Damit kann man cv-Qualifizierungen umwandeln.
Nur das entfernen von const benötigt allerdings einen const_cast. Alles andere (Hinzufügen von const; Hinzufügen/Entfernen von volatile) ist auch mit allen anderen cast-Formen möglich. Das ist auch unproblematisch: im Gegensatz zum Entfernen von const, bedeutet das Entfernen von volatile (sagen wir beim Funktionsaufruf) nicht die potentielle Verletzung einer Garantie beim Aufrufer.
-
camper schrieb:
Don06 schrieb:
Mit const_cast kann man auch volatile wegcasten. const_cast ist ein schlechter Name. Damit kann man cv-Qualifizierungen umwandeln.
Nur das entfernen von const benötigt allerdings einen const_cast. Alles andere (Hinzufügen von const; Hinzufügen/Entfernen von volatile) ist auch mit allen anderen cast-Formen möglich. Das ist auch unproblematisch: im Gegensatz zum Entfernen von const, bedeutet das Entfernen von volatile (sagen wir beim Funktionsaufruf) nicht die potentielle Verletzung einer Garantie beim Aufrufer.
hm.
bist du sicher?Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ C++0x_extensions "ComeauTest.c", line 4: error: static_cast cannot cast away const or other type qualifiers int* p = static_cast<int*>(&i); ^ 1 error detected in the compilation of "ComeauTest.c".
p.S.: hab "i" natürlich volatile gemacht, und nicht const.
-
@otze: klingt sehr einleuchtend was du sagst. ich, in meiner eigenschaft als radikaler c++-hasser, muss jetzt zwar einwenden, dass es sich bei diesen vielen verschiedenen casts offensichtlich um einen konzeptuellen fehler in C++ handelt (welche andere programmiersprache braucht sowas noch?), aber gut, das ist wohl nun mal so.
camper schrieb:
Das ist auch unproblematisch: im Gegensatz zum Entfernen von const, bedeutet das Entfernen von volatile (sagen wir beim Funktionsaufruf) nicht die potentielle Verletzung einer Garantie beim Aufrufer.
begründung?
wenn du volatile von z.b. einem pointer wegmachst, der ursprünglich volatile deklariert wurde, haste auch undefiniertes verhalten (wie bei const): https://www.securecoding.cert.org/confluence/display/seccode/EXP32-C.+Do+not+access+a+volatile+object+through+a+non-volatile+reference
oder gehört du auch zu den leuten, die 'volatile' für sinnlos halten?