Probleme mit Return

  • Fuer was ist denn das -O2 gut? Ich weis irgendwas mit structs aber wuerde gerne genaueres wissen :)

    Die Manpage vom gcc meint dazu:

    Zitat

    -O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff.
    The compiler does not perform loop unrolling or function inlining when you specify -O2. As compared to -O, this
    option increases both compilation time and the performance of the generated code.
    [...]


  • Fuer was ist denn das -O2 gut? Ich weis irgendwas mit structs aber wuerde gerne genaueres wissen :)

    das gibt an wie stark der compiler deinen code optimieren soll. zu starke optimierung kann schon mal in die hose gehen.


    Kurze andere Frage:
    Ich wollte gerade realloc testen in meinem Programm. Es tut auch die gewuenschte groesse reallocieren ABER, es gibt ein paar Werte die komisch sind, im erweiterten Teil. Sind nicht alle aber manche haben den Wert -0 und 3 von ihnen den Wert 39615136492207134461438014706212143104.000000. Nach diesem Wert kommt am ende wieder ein Korrekter Wert im letzen Index, naemlich 0.

    man pages sind eine tolle sache. verwende sie!

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

  • Ich wollte gerade realloc testen in meinem Programm. Es tut auch die gewuenschte groesse reallocieren ABER, es gibt ein paar Werte die komisch sind, im erweiterten Teil. Sind nicht alle aber manche haben den Wert -0 und 3 von ihnen den Wert 39615136492207134461438014706212143104.000000. Nach diesem Wert kommt am ende wieder ein Korrekter Wert im letzen Index, naemlich 0.

    Ich verstehe nicht ganz. Du allokierst zusätzlichen Speicher und wunderst dich, dass in diesem zusätzlichen Speicher nichts Sinnvolles drinnensteht?

    Benutze:

    Code
    *numbers = (float*)realloc(*numbers, stack_size);


    Wäre nicht

    Code
    numbers = (float*)realloc(*numbers, stack_size);

    richtig? Du kriegst ja einen Pointer, mit *numbers=... schreibst du den aber an die Speicherstelle, an die der (alte) Pointer zeigt, anstatt den Pointer numbers an die Stelle zu verbiegen, auf die der Pointer zeigt, den du von realloc kriegst.


  • Wäre nicht

    Code
    numbers = (float*)realloc(*numbers, stack_size);

    richtig? Du kriegst ja einen Pointer, mit *numbers=... schreibst du den aber an die Speicherstelle, an die der (alte) Pointer zeigt, anstatt den Pointer numbers an die Stelle zu verbiegen, auf die der Pointer zeigt, den du von realloc kriegst.


    den code hat er ja leider wieder geloescht, aber imo war es ein pointer auf einen pointer.

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

  • Ja, es ist ein pointer auf ein pointer. Danke fuer die Hinweise.

    ______________________________________________
    (\__/)
    (='.'=)This is Bunny. Copy and paste Bunny into ur
    (")_(")signature to help him gain world domination.
    ______________________________________________
    Windows ist für nur eins gut: WinZip :mad:@ AlgoDat

  • Fuer was ist denn das -O2 gut?


    Paulchen und Kampi haben schon die generelle Erklaerung geliefert. Aber warum ich -O2 als Warning-Flag einstufe, ist sowas da:

    Mit -O2 fuehrt der gcc bestimmte Programmanalysen durch, die er ohne Bitte um Optimierung nicht macht.

    Zitat
    Code
    *numbers = (float*)realloc(*numbers, stack_size);


    Der Rueckgabewert von malloc, realloc etc. braucht und soll in C nicht gecastet werden. Wenn dein Compiler ohne Cast schreit, hast du <stdlib.h> nicht inkludiert, oder du verwendest keinen C-Compiler. (C++ braucht den Cast, und viele Leute kompilieren aus Unwissenheit C als C++. Einige auch absichtlich, weil die Typueberpruefung in einigen solchen Details staerker ist. Ist eine Geschmacksfrage, ich finds nicht so sinnvoll.)

    zu starke optimierung kann schon mal in die hose gehen.


    Erfahrungswerte? -O3 verwend ich fast nie, mit -O2 waeren mir aber noch nie Compilerbugs aufgefallen.

    *plantsch*


  • Der Rueckgabewert von malloc, realloc etc. braucht und soll in C nicht gecastet werden. Wenn dein Compiler ohne Cast schreit, hast du <stdlib.h> nicht inkludiert, oder du verwendest keinen C-Compiler. (C++ braucht den Cast, und viele Leute kompilieren aus Unwissenheit C als C++. Einige auch absichtlich, weil die Typueberpruefung in einigen solchen Details staerker ist. Ist eine Geschmacksfrage, ich finds nicht so sinnvoll.)

    laeuft wohl wirklich auf "geschmacksfrage" hinaus. ich mach das meistens schon. ich bin aber ueberhaupt uebervorsichtig, teilweise unnoetig vorsichtig. ich setze auch bei ifs die '{}' wenn ich nur einen aufruf habe. beim mallocen hab ich mir auch angewoehnt immer 'sizeof()' zu verwenden, auch wenn es ein 'char' ist.


    Erfahrungswerte? -O3 verwend ich fast nie, mit -O2 waeren mir aber noch nie Compilerbugs aufgefallen.

    ich hab den code leider nicht mehr auf lager, also muesztest du mir folgendes glauben: ich hatte einen socket deskriptor mit dem wert '3', was einsichtig ist. nach einem function call (auch wenn ich in der function nur ein 'return' gemacht habe), war der deskriptor '0'. das betraf den default gcc von ubuntu 7.10 mit '-O2'. auf einem anderen pc unter gentoo mit aelterem compiler hat mir der gcc nicht danebengehaut. '-O0' unter ubunut hat aber funktioniert. ich hab dann bei ubuntu einfach einen neueren genommen und dann gings wieder. das war gcc v4.1 vs. v4.2.

    [edit] pc stimmt nicht ganz. es waren beides ppc[/edit]

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

  • Wegen malloc, ich habe gelesen das diese funktion einen pointer vom typ Void zurueckgibt und daswegen mache ich den cast zu float.

    Ich habe mir auch die sysprog Folien angeschaut, daswegen mache ich auch gerade C :P. Da steht der cast auch mit drin. Da ich mit C noch nicht sehr viel gemacht habe habe ich es halt so wie in den Folien gemacht.

    Danke fuer die weitere Erklaerung von -O2. Wundert mich aber schon das bei einer uninitialized variable der normale compiler ohne die O2 option net meckert.

    ______________________________________________
    (\__/)
    (='.'=)This is Bunny. Copy and paste Bunny into ur
    (")_(")signature to help him gain world domination.
    ______________________________________________
    Windows ist für nur eins gut: WinZip :mad:@ AlgoDat

  • Wegen malloc, ich habe gelesen das diese funktion einen pointer vom typ Void zurueckgibt und daswegen mache ich den cast zu float.


    Ja, tut sie. Aber Pointer vom Typ void werden in C automatisch auch ohne Cast in Pointer auf andere (Daten-)Typen umgewandelt. So wie diverse Zahlentypen auch ohne Cast ineinander umgewandelt werden.

    Der Cast ist kein Fehler an sich, er koennte aber den Fall verstecken, dass man eben malloc verwendet, ohne <stdlib.h> inkludiert zu haben. Dann ist es ein Cast von int auf einen Pointertyp, und der koennte theoretisch schiefgehen, wenn ints und Pointer unterschiedlich gross sind.

    Generell habe ich eine Abneigung gegenueber unnoetigen Casts. Schlimm sind die "ich-ignoriere-den-Rueckgabewert-dieser-Funktion"-Casts; dass der Wert ignoriert wird, sieht man auch so. An die Spitze getrieben habe ich mal Code von einem respektablen Mitglied dieses Forums gesehen, der Statements dieser Form enthalten hat:

    Code
    (void) free(ptr);


    Das ist weder "defensives Programmieren" noch selbstdokumentierender Code, das ist nur noch programmiertechnischer Dadaismus aus Gewohnheit, und als solcher kein guter Programmierstil.

    Jeder Cast sollte was aussagen, und dieser sagt aus "ich weiss nicht, was free zurueckgibt, es ist mir auch egal, ob es einen Fehler zurueckgeben koennte (!), und ich machs halt so, weil mir eingetrichtert wurde, dass mans halt immer so macht". Aehnlich ist mein Eindruck, wenn ich Code lese, der malloc castet -- "aha, anderer Pointertyp, ich caste mal, weil ich das Typsystem meiner Sprache nicht so gut kenne, wie ich sollte". Ich respektiere da natuerlich die gut begruendete entgegengesetzte Meinung, aber das ist wie gesagt mein Eindruck, wenn ich den nackten Code sehe. Hab mir gedacht, ich erwaehns mal, eigene Meinung bilden kann man sich dann auch noch :)

    Zitat

    Ich habe mir auch die sysprog Folien angeschaut, daswegen mache ich auch gerade C :P. Da steht der cast auch mit drin.


    Mit Verlaub, die Sysprog-Menschen sind nicht die kompetentesten C-Programmierer der Welt. Aber mir ist auch klar, dass man das als Anfaenger nicht so einschaetzen kann :)

    Ich begruende diese Aussage wohl besser anhand von zwei nicht repraesentativen Beispielen. In einer Sysprog-Abgabe hatte ich Code, der mit Eventcountern irgendwas gemacht hat, ich erinner mich an die Funktionsnamen nicht mehr, aber der Code hatte die Form

    Code
    eventcounter c;
    for (c = anfang(); c != der_event_auf_den_ich_warte(); c = naechster_event())
    {
        ...
    }


    Die Tutorin wollte das nicht akzeptieren, hat ewig nicht geglaubt, dass man mit einer for-Schleife was anderes machen kann als Sachen zaehlen.

    Und noch viel schlimmer, bei einem der Tests kam die Frage "was ist das Ergebnis von diesem Programm", wobei im Code sowas gestanden ist:

    Code
    int array[42];
    array++;


    Ich hab waehrend dem Test den einen Assi hergerufen und ihm gesagt, dass das nicht C ist, er darauf "dochdoch, Arrays und Pointer sind das selbe in C". Stimmt nicht, sie sind aehnlich, haben aber bestimmte gravierende Unterschiede, unter anderem, dass man obiges nicht machen kann. Gut, das ist ja schlimm genug, und ich habs auch am Pruefungsbogen verzeichnet. Und was machen die dann? Statt ihren Fehler zuzugeben, wird nach dem Test eine Mail ausgesendet mit einer Aussage der Art "viele Studenten hatten bei einem Beispiel Verstaendnisprobleme", und wer nichts einigermassen plausibles hingeschrieben hat, kann zu einem zehnminuetigen Nachtest ueber ein aehnliches Beispiel antreten.

    So, Frust von der Seele geredet :)

    Zitat

    Danke fuer die weitere Erklaerung von -O2. Wundert mich aber schon das bei einer uninitialized variable der normale compiler ohne die O2 option net meckert.


    Wie gesagt, es ist dafuer eine Analyse noetig, die fuer Optimierungen wichtig ist, ansonsten nicht. Die ist jetzt nicht wirklich aufwendig, aber wenn man den Compiler nicht um Optimierung bittet, moechte er trotzdem so schnell wie moeglich laufen und keine unnoetigen Analysen durchfuehren.

    *plantsch*

  • Mit Verlaub, die Sysprog-Menschen sind nicht die kompetentesten C-Programmierer der Welt. Aber mir ist auch klar, dass man das als Anfaenger nicht so einschaetzen kann :)

    Zur Verteidigung der Sysprogger muss man sagen, dass sie schon gesagt haben, dass man alle Rückgabewerte behandeln soll. Das (void) signalisierte ihnen, dass mans bewusst nicht tut, und nicht nur einfach vergessen hat. Machts zwar nicht besser, aber immerhin leichter, beim Test Punkte abzuziehen. "Du hast ja den Fehler bewusst nicht behandelt!!11"

    Wo sie aber meiner Meinung nach noch viel gröber ins Klo gegriffen haben:

    In meinem Jahrgang konnten sich ein Haufen Leute (inklusive mir) nicht für den Test anmelden, uns ist dabei schon aufgefallen, dass 2000er Matrikelnummern (die ja mit 00 starten) Probleme machen. Anstatt einfach auf die Website zu schreiben, dass diese Leute sich nicht anmelden können, haben sie zu dem Problem ansonsten geschwiegen (und es bis zum Test nicht ausgebessert).

    Zum Test hats dann ein Beispiel gegeben, wo man Matrikelnummern als Parameter einlesen soll, und dann als int:shinner: an irgendeine Funktion übergeben soll. Tja, schlimm genug, dass man seine eigenen Bugs nicht ausbessert, man lässt sie auch noch beim Test von den Studenten nachprogrammieren. :rofl:

    So, Frust von der Seele geredet :)

    Ich jetzt auch.:wave:

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • Nach den zwei letzen Posts kann ich mich ja richtig auf Sysprog freuen :shinner:

    Aber eine kurze Frage zu deinem Test Beispiel Plantschkuh!,

    ich sehe da kein pointer :engel:. Ich sehe das array und dann den Versuch es zu inkrementieren, was ich so verstehen wuerde das es das Array groesser machen soll. Ich wuerde halt sage das der Code gar nicht funktioniert. Aber ich wuerde hier nie an einen Pointer denken, die Antwort vom Assi hat mich deshalb verwirrt.

    Generelle Frage zu dem Casten. Bei sollchen Funktionen wie free(), sollte ma da dann einen int return wert haben zum Beispiel und diesen Wert dann pruefen und eventuell was ausgeben? Ich denke das waere Fehler Behandlung in diesem Sinne oder? Z.B. -1 zurueck geben wenn es nicht geklappt hat.

    Danke nochmals an alle fuer die guten Erklaerungen und ich werde sicher noch ein paar Fragen vor dem Winter Semester haben :verycool:

    ______________________________________________
    (\__/)
    (='.'=)This is Bunny. Copy and paste Bunny into ur
    (")_(")signature to help him gain world domination.
    ______________________________________________
    Windows ist für nur eins gut: WinZip :mad:@ AlgoDat

  • Generelle Frage zu dem Casten. Bei sollchen Funktionen wie free(), sollte ma da dann einen int return wert haben zum Beispiel und diesen Wert dann pruefen und eventuell was ausgeben? Ich denke das waere Fehler Behandlung in diesem Sinne oder? Z.B. -1 zurueck geben wenn es nicht geklappt hat.

    Manpages lesen. In der Manpage von free() steht was von void, da wird nichts zurückgegeben ("free() returns no value.").

    malloc() gibt einen Pointer auf den allokierten Speicherbereich zurück. Es kann aber sein, dass kein Speicher allokiert werden kann, etwa weil das Programm schon zu viel Speicher allokiert hat (es gibt eine systemabhängige Obergrenze, wie viel Speicher ein Programm allokieren darf) oder weil kein Speicher mehr verfügbar ist. Die Manpage von malloc() sagt dir, dass in einem solchen Fall NULL zurückgegeben wird. Wenn du dieses NULL dann als Pointer verwendest, hast du einen Segmentation Fault. Du kannst aber überprüfen, ob der Rückgabewert von malloc() NULL ist und in deinem Programm entsprechend reagieren.


  • Aber eine kurze Frage zu deinem Test Beispiel Plantschkuh!,

    ich sehe da kein pointer :engel:. Ich sehe das array und dann den Versuch es zu inkrementieren, was ich so verstehen wuerde das es das Array groesser machen soll. Ich wuerde halt sage das der Code gar nicht funktioniert. Aber ich wuerde hier nie an einen Pointer denken, die Antwort vom Assi hat mich deshalb verwirrt.

    wie plantschkuh schon sagte verhalten sich pointer und arrays aehnlich. der gezeigte code sollte wohl nicht das array vergroeszen, sondern die adresse eins weiter zaehlen.

    hier ein kleines bsp, das zeigt wie wie pointer und zugriff als array funktionieren:

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!