Rückgabe von Objekten
-
Shade Of Mine schrieb:
und das musst du verstehen. sonst ist die diskussion sinnlos.
[...]
Du hast nichts verstandenEine Diskussion macht keinen Sinn
[...]
wir sind am ende - es macht keinen sinn weiter zu reden.Und die Güte, ihm (und den anderen) dies Sache genauer zu erklären, besitzt du nicht?
Bei dir ist mir schon öfters aufgefallen, dass du teilweise einfach Sätze in den Raum wirfst, ohne sie zu begründen. Du gehst einfach davon aus, man wisse, was du damit meinst.
Beispiel:
Shade Of Mine schrieb:
Ein simples Beispiel fuer preconditions ist:
ofstream s; s<<"foo";
s<<"foo"
ist eine precondition verletzung. Recht triviale Sache eigentlich.Und dann noch etliche Male das Wort "precondition" zu erwähnen. Da erstaunt es mich nicht, dass Dravere der Zusammenhang fehlt.
Oder im anderen Thread:
iterator und const_iterator sind nicht verwandt.
Es ist ja nicht schlimm, aber wenn man dann nachfragt, solltest du nicht genervt antworten (was im anderen Thread schliesslich auch gut klappte). Es ist auch nicht böse gemeint, aber vielleicht solltest du dich etwas mehr darauf achten.
-
Nexus schrieb:
Bei dir ist mir schon öfters aufgefallen, dass du teilweise einfach Sätze in den Raum wirfst, ohne sie zu begründen. Du gehst einfach davon aus, man wisse, was du damit meinst.
Beispiel:Shade Of Mine schrieb:
Ein simples Beispiel fuer preconditions ist:
ofstream s; s<<"foo";
s<<"foo"
ist eine precondition verletzung. Recht triviale Sache eigentlich.Und dann noch etliche Male das Wort "precondition" zu erwähnen. Da erstaunt es mich nicht, dass Dravere der Zusammenhang fehlt.
braucht man würklich länger als 10 sekunden, um zu sehen, daß "foo" nicht in die datei geschrieben wird (tip: in welche datei?)?
klar steigen manche leute aus der diskussion aus, wenn andere leute die klarsten argumente dutzendfach ignorieren und irgendwelchen mist verzapfen, der allein durch die ignoranz des erfinders unwiderlegbar ist.
-
volkard schrieb:
braucht man würklich länger als 10 sekunden, um zu sehen, daß "foo" nicht in die datei geschrieben wird (tip: in welche datei?)?
Es ging mir hier nicht um die Precondition an sich, sondern um den Zusammenhang zum Thema. Und der war wirklich nicht sofort ersichtlich.
-
Nexus schrieb:
volkard schrieb:
braucht man würklich länger als 10 sekunden, um zu sehen, daß "foo" nicht in die datei geschrieben wird (tip: in welche datei?)?
Es ging mir hier nicht um die Precondition an sich, sondern um den Zusammenhang zum Thema. Und der war wirklich nicht sofort ersichtlich.
Was genau ist nicht klar? Ich erklaere es gerne...
uU habe ich auch etwas falsch verstanden - aber soweit ich die Sache hier verstanden habe ging es darum dass ein Zeiger bedeutet dass das Objekt NULL sein kann und deshalb volkards Variante der Kennzeichnung von OUT parametern gegen die Sprache arbeitet.
Oder liege ich hier falsch?
-
Nexus schrieb:
volkard schrieb:
braucht man würklich länger als 10 sekunden, um zu sehen, daß "foo" nicht in die datei geschrieben wird (tip: in welche datei?)?
Es ging mir hier nicht um die Precondition an sich, sondern um den Zusammenhang zum Thema. Und der war wirklich nicht sofort ersichtlich.
das begann mit
Ich finde so einen Code eher fehleranfällig und unhandlich, erst recht um die Funktion zu implementieren, da man eine Fehlerbehandlung einführen muss, falls ein Null-Zeiger übergeben wird.
da hatte ich versucht, einspruch zu erheben. natürlich *muss* man das nicht machen. im späteren verlauf kamen dann an passender stelle auch begriffe wie preconditions.
-
volkard schrieb:
Ich finde so einen Code eher fehleranfällig und unhandlich, erst recht um die Funktion zu implementieren, da man eine Fehlerbehandlung einführen muss, falls ein Null-Zeiger übergeben wird.
da hatte ich versucht, einspruch zu erheben. natürlich *muss* man das nicht machen. im späteren verlauf kamen dann an passender stelle auch begriffe wie preconditions.
Es gibt nunmal Anhänger des Ansatzes, das man die Fehlbedienung möglichst ausschließen will. Jede bereits im Vorfeld vermeidbare Precondition halte ich für sinnvoll, da sie die Fehlersuche erleichtert (Precondition muss man uU nachschauen, und sie sind nicht immer an den Parametern oder den Bezeichnern erkennbar).
cu André
-
Bashar schrieb:
Shade Of Mine schrieb:
volkards methode out parameter als Zeiger setzen ist unueblich
Sie wird auch von John Lakos ("Large Scale C++ Software Design") empfohlen.
Was rät Lakos eigentlich für den Fall, dass
a) ein InputParameter (= kein Zeiger) optional ist?
b) ein bereits als Zeiger übergebener Parameter als Inputparameter an eine weitere Funktion weitergegeben werden soll?oder in Code:
// a) mach_nix_mit_optionalem_parm( ??? ); // b) void mach_was_mit_parm(int* x) { *x = 0; mach_nix_mit_parm( ??? ); }
Gruß,
Simon2.
-
asc schrieb:
Es gibt nunmal Anhänger des Ansatzes, das man die Fehlbedienung möglichst ausschließen will. Jede bereits im Vorfeld vermeidbare Precondition halte ich für sinnvoll, da sie die Fehlersuche erleichtert (Precondition muss man uU nachschauen, und sie sind nicht immer an den Parametern oder den Bezeichnern erkennbar).
Ist dir bewusst, dass du damit aussagst dass man Zeiger deshalb meiden soll weil man mit ihnen Fehler machen kann?
Zeiger zu meiden weil es Zeiger sind, ist einfach fragwürdig. Sehen wir uns zB Java an - da verwendet man nur Zeiger und hat Referenzen gleich komplett weggelassen und dort würde niemand so eine Diskussion führen.
Das Problem ist, dass es immer heisst dass Zeiger böse sind. Aber das sind sie nicht. Nur Anfänger sollten sie meiden. Das wirkliche Problem mit Zeigern sind nämlich wilde Zeiger und das kann einem bei Referenzen genauso passieren.
Null Pointer sind nichts unerwartetes...
@Simon2:
Ich sehe hier kein Problem. Einfach
mach_nix_mit_parm(*x)
schreiben
da die Funktion x entweder by value oder by const reference nimmt - je nachdem welchen Typ x hat. Die beiden Funktionen sind nämlich nicht verwandt oder sonst etwas - es sind einfach 2 freie Funktionen - warum sollten sie voneinander abhängig sein?
-
Shade Of Mine schrieb:
...
@Simon2:
Ich sehe hier kein Problem. Einfach
mach_nix_mit_parm(*x)
schreiben
...hmmm, wie passt das in die Logik:
"... beim call 'f(x)' weiß ich, dass der Parameter nicht verändert wird, bei 'f(&x)' weiß ich, dass er verändert wird..."?
Das könnte man zwar erweitern auf "...auch bei 'f(*x)' weiß ich ....", aber das Ganze wird doch ziemlich trashig bei// b) void mach_was_mit_parm(int* x, int** y) { *x = 0; mach_was_mit_parm2(x); // hoppla ... hier "sieht" man ja gar nicht, dass man etwas macht mach_was_mit_parm2(*x); // hier erst Recht nicht .... }
und bei meinem anderen Beispiel lag der Schwerpunkt darauf, dass der Parameter optional ist. Da wird ein call-by-value jedenfalls eher "fingerbrechig" bzw. setzt seltsame und ansonsten unnötige Anforderung an den Typ (Def-konstruierbar, ...).
Gruß,
Simon2.
-
Da müsse man ja dann so vorgehen:
mach_was_mit_parm2(&(*x));
Oder man muss wissen, dass x ein Zeiger ist..
Aber da kann man ja gleich wissen, dass die Funktion etwas verändern kann..
-
drakon schrieb:
Da müsse man ja dann so vorgehen:
mach_was_mit_parm2(&(*x));
...
oh ja und dann bei Pointerpointern dann
mach_was_mit_parm2(&(******y));
(nicht vergessen, sich bei jedem "" überlegen, ob man dereferenzieren darf, der operator()/operator&() evtl. überladen wurde, ....)
Alles nur, um ein "&" in den Aufruf zu bekommen...Gruß,
Simon2.
-
Wieso wird eigentlich dauernd versucht, mit Sprachmitteln etwas hinzubiegen, sodass man angeblich schneller erkennt, dass der Parameter verändert wird? In den letzten Posts sieht man schnell, worauf das hinauslaufen kann.
Ich bleibe dabei, dass wenn eine Manipulation wirklich nicht aus dem Kontext ersichtlich ist (beispielsweise durch sprechende Funktionsnamen), ein guter Kommentar immer noch am meisten hilft. Zumal man damit auch ausdrücken kann, wie das Argument verändert wird. Bei
func(&x);
hat man ja immer noch keine Garantie, dassx
tatsächlich verändert wird (je nach Funktionsanweisungen halt).
-
Obwohl ich eigentlich eurer Meinung bin (Nexus und Simon2), muss ich halt, weil es sonst atm niemand macht ein paar Gegenargumente bringe.
oh ja und dann bei Pointerpointern dann
mach_was_mit_parm2(&(******y));
So viele Pointer braucht man grundsätzlich nie. Ansonsten ist es falsch designed.
hat man ja immer noch keine Garantie, dass x tatsächlich verändert wird
Um das ging es ja auch nicht. Es ging darum möglichst schnell zu erkennen, dass die Möglichkeit besteht, dass die Funktion das Objekt verändert.
-
Vielleicht sollten wir erst einmal lernen zu verstehen warum volkard vorschlägt es so zu machen. Es geht dabei nicht darum einfach mehr zu schreiben weil es lustig ist - sondern es geht darum ein konkretes problem zu lösen.
Ich habe ein Objekt und das ist in einem ordentlichen Zustand und etwas später ist es das nicht mehr. Warum?
Indem ich nun weiss dass überall dorthin wo ich das Objekt als Zeiger übergebe Änderungen stattfinden können, kann ich sehr sehr schnell die entsprechenden funktionen identifizieren. Denn ich weiß ja ob x ein Zeiger ist oder nicht -> ich muss nur umdenken:
foo(*x)
heisst nicht verändert aber
foo(x)
heisst möglicherweise verändert.Und das ist die Idee dahinter.
Es ist eine Lösung für ein Problem. Nicht mehr und nicht weniger.
Ich selber bin kein Fan davon, aber das hindert mich nicht daran die Idee dahinter zu verstehen und ok zu finden.
-
drakon schrieb:
...So viele Pointer braucht man grundsätzlich nie. Ansonsten ist es falsch designed. ;)...
Naja, ich würde das ja auch nie tun, aber wenn man halt überall mit Pointern auch "Veränderbarkeit" (und vielleicht noch ein paar andere Dinge) ausdrücken möchte, könnte es schon dazu kommen...
Wie soll das Ganze eigentlich bei templates aussehen? Oder bei Smartpointern? Oder ...
drakon schrieb:
...Obwohl ich eigentlich eurer Meinung bin (Nexus und Simon2), muss ich halt, weil es sonst atm niemand macht ein paar Gegenargumente bringe....
Man muss nicht auf ein Pferd steigen, bloß weil keiner (mehr) drauf sitzt.
drakon schrieb:
...Um das ging es ja auch nicht. Es ging darum möglichst schnell zu erkennen, dass die Möglichkeitbesteht, dass die Funktion das Objekt verändert.
Aha - das bedeutet: Ich weiß nicht nur NICHT, ob die Funktion nach der "Zeiger=Veränderung"-Regel gestrickt ist, sondern auch nicht, ob die Funktion (wenn sie es denn wäre) den Parameter tatsächlich verändert.
Gerade bei "schnell erkennen" wäre ich dafür, dass meine Sicherheit durch eine Regel wächst und nicht abnimmt.Gruß,
Simon2.
-
Simon2 schrieb:
Aha - das bedeutet: Ich weiß nicht nur NICHT, ob die Funktion nach der "Zeiger=Veränderung"-Regel gestrickt ist, sondern auch nicht, ob die Funktion (wenn sie es denn wäre) den Parameter tatsächlich verändert.
bei x+=y weißt du auch nicht, ob x geändert wird. und das ist sehr sehr oft so, daß ein funktionsaufruf nur die möglichkeit hat, was zu ändern und in manchen fällen doch nix ändert.
dein argument war so flach, als hättest du noch nie programmiert, daß ich auf so nen kinderkram einfach keine weitere lust habe. du weißt, daß ich programmiertechnisch kein vollidiot bin, also erwäge einfach die möglichkeit, daß mein ansinnen auch seine berechtigung hat. übrigens ist das argument, daß eine stilregel nix bringt, weil sie nix bringt, wenn sich keiner dran hält, leer.
-
Shade Of Mine schrieb:
...
Sehe ich auch so und darum habe ich auf simons Post so geantwortet..
Man muss nicht auf ein Pferd steigen, bloß weil keiner (mehr) drauf sitzt.
Das war eigl. nur ein kleiner Joke, der gerade gepasst hat, aber ich wollte halt die Idee dahinter verteidigen, welche ich schon auch verstehe. (auch wenn ich es so nicht machen würde..)
Aha - das bedeutet: Ich weiß nicht nur NICHT, ob die Funktion nach der "Zeiger=Veränderung"-Regel gestrickt ist, sondern auch nicht, ob die Funktion (wenn sie es denn wäre) den Parameter tatsächlich verändert.
Es geht ja in erster Linie ja nicht darum zu wissen, welche Funktionen etwas verändern, sonder zuerst einmal darum dijenigen herauszufilter, welche es sicher nicht machen.
@volkard:
Was ist dann aber z.B in einer Klasse? Wenn du dort z.B rausfinden musst, wo eine Member verändert wird, dann musst du ja dennoch alle Funktionen durchsuchen. (respektive dijenigen, welche auch aufgerufen werden..).
Kann es sein, dass das demfall noch eher von C her kommt, wo alles durch einen Paramter durch muss (mal abgesehen von globals)?
-
drakon schrieb:
Kann es sein, dass das demfall noch eher von C her kommt, wo alles durch einen Paramter durch muss (mal abgesehen von globals)?
ja. der fall, daß man out-objekte in der parameterliste hat, ist sehr selten. kommt vielleicht sogar nur als folge schlechter bibliotheken vor (außer beim globalen swap).
wie sieht das eigentlich mit rvalue referenzen aus? ergibt foo const&& f überhaupt sinn? mit && gebe ich f zur stillen zerstörung frei und mit const verhindere ich es wieder. oder hab ich da was falasch verstanden? muß mal nachdenken, was das bewirkt.
-
volkard schrieb:
drakon schrieb:
Kann es sein, dass das demfall noch eher von C her kommt, wo alles durch einen Paramter durch muss (mal abgesehen von globals)?
ja. der fall, daß man out-objekte in der parameterliste hat, ist sehr selten. kommt vielleicht sogar nur als folge schlechter bibliotheken vor (außer beim globalen swap).
Ich verstehe jetzt nicht ganz, was du meinst. Es ging mir darum, dass, wenn du Klasesn hast und eine Member kontrollieren musst, die ihren Zustand wechselt und du wissen musst, wo das passiert, dann musst du unter Umständen jede Funktion, die zur Klasse gehört, wo die Meber drin ist, untersuchen. Und in C++ tendiert ja alles dazu in Klassen zu sein..
-
drakon schrieb:
Es ging mir darum, dass, wenn du Klasesn hast und eine Member kontrollieren musst, die ihren Zustand wechselt und du wissen musst, wo das passiert, dann musst du unter Umständen jede Funktion, die zur Klasse gehört, wo die Meber drin ist, untersuchen. Und in C++ tendiert ja alles dazu in Klassen zu sein..
ja, stimmt.