Zwei kleine Selbsttests über euer C-Wissen


  • Mod

    Shiba schrieb:

    Ich habs jetzt mal mit ggc kompiliert und das prophezeite Ergebnis nicht hinbekommen. Habe ich eigentlich auch nicht erwartet.
    Aber den Link werde ich studieren und meinen Horizont erweitern.
    Danke.

    Also ich kann es mit gcc 4.4 reproduzieren. Irgendwie habe ich stark den Verdacht, dass du irgendwo unabsichtlich optimierst. So abgefahren undefiniert ist der Effekt nämlich nicht, sondern ziemlich genau was man bei unoptimiertem Code auf herkömmlichen Compilern und Maschinen erwarten würde.



  • Ist nicht ausgeschlossen, das ich da Fehler mache.
    Werde mir die Optimierung und die Kompilation mit gcc nochmal vornehmen.
    Vielen Dank-



  • Ich finde Folie 370 ist immer noch crap.

    "Wenn man schon irgendwo new array benutzt" sollte man ein try catch drum herum bauen falls nicht genügend speicher zur Verfügung steht.

    Außerdem sollte man für solche Zwecke eher std::size_t übergeben und nicht int.

    Desweiteren sollte man prüfen ob std::size_t nicht 0 ist.

    Wenn irgendwas beim new falsch läuft sollte man den Zeiger auf NULL setzen.

    Im Destruktor muss eine if(v) { delete v [] };

    Da ist dem Autor wahrscheinlich die Puste ausgegangen? Wohl eher ein C Programmierer???



  • Folie 382 hat auch überhaupt nichts mit C++ zu tun. Das macht man einfach so nicht.

    Außerdem wird nirgendwo return EXIT_SUCCESS; angegeben obwohl es eigentlich zum guten Ton gehört.



  • asdsadsa schrieb:

    "Wenn man schon irgendwo new array benutzt" sollte man ein try catch drum herum bauen falls nicht genügend speicher zur Verfügung steht.

    Warum? Mache ich nie. Ist der Speicher alle, ist sowieso meist alles zu spaet.

    Desweiteren sollte man prüfen ob std::size_t nicht 0 ist.

    Oder man definiert einfach: "should not be zero".

    Im Destruktor muss eine if(v) { delete v [] };

    Nein, delete funktioniert auch auf Null-Pointern. Deswegen sollten sie nicht auf 0 gesetzt werden, um ein mehrmaliges Freigeben zu erkennen.



  • knivil schrieb:

    Warum? Mache ich nie. Ist der Speicher alle, ist sowieso meist alles zu spaet.

    Es muss nicht sein dass du nur das letzte Stück des Speichers belegst, es kann sein dass du auf einmal zuviel Speicher brauchst. Auch generell gesehen ist es nie zuspät eine Exception zu fangen und das Programm evtl. kontrolliert zu beenden.

    knivil schrieb:

    Oder man definiert einfach: "should not be zero".

    Hö?

    knivil schrieb:

    Im Destruktor muss eine if(v) { delete v [] };

    Nein, delete funktioniert auch auf Null-Pointern. Deswegen sollten sie nicht auf 0 gesetzt werden, um ein mehrmaliges Freigeben zu erkennen.[/quote]

    Wie möchtest du sonst erkennen ob du diesen Pointer nicht schon einmal gelöscht hast?



  • asdsadsa schrieb:

    Wie möchtest du sonst erkennen ob du diesen Pointer nicht schon einmal gelöscht hast?

    Muß ich nicht erkennen.
    Zu jedem new schreibe ich ein passendes delete und gut ist's.
    Ich schreibe keine wilde Horde von deletes, wovon das erste löschen darf und alle weiteren es zur Sicherheit auch mal probieren.



  • Nein, wenn im C++-Code ein delete[] steht, hat der Programmierer (noch) nichts von RAII gehört (vector).

    Aber in C++ braucht man in main nichts implizit zurückzugeben, kein Returnwert (und zwar nur in main), bedeutet für den Compiler return 0; .

    Und Makros wie EXIT_SUCCESS bracht sowieso kein Mensch.

    Zusatz (Post gerade erst gesehen): Zeiger auf 0 zu setzen, verschiebt nur Probleme, lieber nicht auf 0 setzen und es noch während der Entwicklung ordentlich krachen lassen, ein mehrfaches delete auf einen Speicherbereich ist ein Bug.



  • volkard schrieb:

    asdsadsa schrieb:

    Wie möchtest du sonst erkennen ob du diesen Pointer nicht schon einmal gelöscht hast?

    Muß ich nicht erkennen.
    Zu jedem new schreibe ich ein passendes delete und gut ist's.
    Ich schreibe keine wilde Horde von deletes, wovon das erste löschen darf und alle weiteren es zur Sicherheit auch mal probieren.

    Davon kannst in einem Unternehmen gar nicht ausgehen. Man sollte es so schwer wie möglich machen. Zwar nicht mit "Koste es was es wolle" aber in diesem Fall ist es trivial.



  • Hmmh schrieb:

    Nein, wenn im C++-Code ein delete[] steht, hat der Programmierer (noch) nichts von RAII gehört (vector).

    So siehts aus.

    [quote="Hmmh"]Aber in C++ braucht man in main nichts implizit zurückzugeben, kein Returnwert (und zwar nur in main), bedeutet für den Compiler return 0; .[/code]

    Und 0 gilt nicht für alle System als o.k.

    Hmmh schrieb:

    Und Makros wie EXIT_SUCCESS bracht sowieso kein Mensch.

    Um das Problem von oben zu vermeiden solltest du dieses Makro verwenden.

    Hmmh schrieb:

    Zusatz (Post gerade erst gesehen): Zeiger auf 0 zu setzen, verschiebt nur Probleme, lieber nicht auf 0 setzen und es noch während der Entwicklung ordentlich krachen lassen, ein mehrfaches delete auf einen Speicherbereich ist ein Bug.

    Es verschiebt sie nicht weil in keinem Fall gelöscht werden kann. Einfache Regel( delete x; x = NULL ) und beim Benutzen immer brav if. Wenn man sich das einmal angewöhnt hat dann ist man innerhalb der Klasse sicher. Man muss hier auch den Endanwender betrachten. Wenn nur ich die Klasse nutzen würde dann hätte ich es auch anders gemacht. Davon kann man i. d. R. nicht immer ausgehen.

    Im Prinzip ist es auch überflüssig darüber zu diskutieren weil delete von sich aus crap ist.



  • asdsadsa schrieb:

    Einfache Regel( delete x; x = NULL ) und beim Benutzen immer brav if. Wenn man sich das einmal angewöhnt hat dann ist man innerhalb der Klasse sicher.

    Das ist Anfängermist aus besonders schlechten Büchern.

    asdsadsa schrieb:

    Man muss hier auch den Endanwender betrachten. Wenn nur ich die Klasse nutzen würde dann hätte ich es auch anders gemacht. Davon kann man i. d. R. nicht immer ausgehen.

    Man muß immer davon ausgehen, daß die Mitarbeiter zwar doof sind, aber auch keine blutigen Anfänger mehr. Sonst baut man Unfug-Code, um die Anfänger zu schützen, und verdirbt damit doch zu viel. Du schreibst ja auch nicht i=i+1 statt ++i, weil es Leute geben könnte, die ++i nicht lesen können. Den Zeiger danach auf 0 zu setzen ist normalerweise vollkommen nutzlos.
    Ich habe es sogar schon in einem Destruktor gesehen. War der nicht auch von Wolf? Im Destruktor, wo das Member dann sofort stirbt, wie sinnlos kann man sein?!

    asdsadsa schrieb:

    Im Prinzip ist es auch überflüssig darüber zu diskutieren weil delete von sich aus crap ist.

    Nee. Wenn jemand eine sehr schlechte Angewohnheit als guten Stil verkauft, soll man schon widersprechen. ( delete x; x = NULL ) ist Obermist.

    Aber frag das besser nochmal im C++-Forum. Hier ist C und da muß man nicht Feinheiten über die Verwendung von delete ausloten.



  • volkard schrieb:

    Wolf?

    Wenn du DEN Wolf meinst... Gott stehe dir bei 😉

    Ich bin ja bereit dazu zu lernen aber als Wolfs Schaf bezeichnet zu werden verstößt gegen ALLE guten C++ Sitten !! Ich glaube sogar dass er auch im C Forum verpönt ist. Er hat ja auch ein C Buch.

    volkard schrieb:

    Nee. Wenn jemand eine sehr schlechte Angewohnheit als guten Stil verkauft, soll man schon widersprechen. ( delete x; x = NULL ) ist Obermist.

    Ich will dir ja folgen aber damit hast du noch immer nicht geklärt wie ich prüfen soll ob dieses Array nicht bereits zuvor gelöscht wurde?!

    Weitere Frage in die Runde. Verstößt das hier gegen Point Sequence? Ja/Nein/Warum?

    int i,j,k;
    i = 1 + 2;
    j = 2 * i;
    k = j * i + 3;
    


  • asdsadsa schrieb:

    Ich will dir ja folgen aber damit hast du noch immer nicht geklärt wie ich prüfen soll ob dieses Array nicht bereits zuvor gelöscht wurde?!

    Ich weiß nicht, um welches Array es geht und ich weiß nicht, weshalb man prüfen sollte, ob es schon gelöscht wurde; also weshalb man überhaupt annehmen sollte, daß es mehrmals zu löschen versucht werden könnte.



  • asdsadsa schrieb:

    Weitere Frage in die Runde. Verstößt das hier gegen Point Sequence? Ja/Nein/Warum?

    int i,j,k;
    i = 1 + 2;
    j = 2 * i;
    k = j * i + 3;
    

    Nein. Anweisungsende (;) zählt auch als Sequence Point.



  • asdsadsa schrieb:

    Weitere Frage in die Runde. Verstößt das hier gegen Point Sequence? Ja/Nein/Warum?

    int i,j,k;
    i = 1 + 2;
    j = 2 * i;
    k = j * i + 3;
    

    Gegen was soll das verstoßen? Das sind eine Variablen-Definition und drei völlig legale Anweisungen (Zuweisung), die in der angegebenen Reihenfolge abgearbeitet werden.

    PS: Die Sequenz "delete x; x=NULL;" sorgt nur dafür, daß du über genau DIESEN Zeiger nichts mehr kaputtmachen kann. Gegen double delete hilft es überhaupt nicht, da mußt du dein Design schon von vornherein so aufbauen, daß du immer weißt wer den reservierten Speicher gerade benutzen will (Stichwort: Smart Pointer).



  • volkard schrieb:

    asdsadsa schrieb:

    Weitere Frage in die Runde. Verstößt das hier gegen Point Sequence? Ja/Nein/Warum?

    int i,j,k;
    i = 1 + 2;
    j = 2 * i;
    k = j * i + 3;
    

    Nein. Anweisungsende (;) zählt auch als Sequence Point.

    Super dann wäre dies hier:

    int i,j;
    
    i = 1;
    j = i+++i--;
    j = (j--)-j--;
    --i = i;
    

    undefiniert?!



  • Zeile 4 und 5: ja.
    (Zeile 5 genau genommen sogar doppelt)



  • Fake oder Echt schrieb:

    Zeile 4 und 5: ja.
    (Zeile 5 genau genommen sogar doppelt)

    Supi, und wieder was dazu gelernt. Danke an alle.


Anmelden zum Antworten