Problem mit Macros



  • Hallo!

    Ich habe aktuell ein Klemmer mit den Macros im Preprozessor.

    Ich habe folgende Macros definiert:

    #define MALLOC(type,n) (type*)FuncTable->MemAlloc->T_malloc_size_t( (n) * sizeof(type))
    //
    #define FREE(ptr) FuncTable->MemAlloc->T_free(ptr)
    #define COND_FREE(ptr){ \
    if (ptr != NULL){ \
      FREE(ptr); \
      (ptr)=NULL; \
      } \
     }
    
    //[...]
    
    Array = MALLOC (int, AnzahlItems);
    
    //[...]
    
    COND_FREE (Array);
    

    Das tut soweit was es soll

    wenn ich aber folgendes mache (MALLOC mehrzeilig, um noch was einzubauen)

    :
    
    [code]
    #define MALLOC(type,n){\
     (type*)FuncTable->MemAlloc->T_malloc_size_t( (n) * sizeof(type)) \
    }
    //
    #define FREE(ptr) FuncTable->MemAlloc->T_free(ptr)
    #define COND_FREE(ptr){ \
    if (ptr != NULL){ \
      FREE(ptr); \
      (ptr)=NULL; \
      } \
     }
    
    //[...]
    
    Array = MALLOC (int, AnzahlItems);
    
    //[...]
    
    COND_FREE (Array);
    

    Dann bekomme ich vom Compiler die Meldung
    error: expected expression before '{' token

    Wo klemmts dabei? (in der Hoffnung alles korrekt kopiert zu haben...)

    Ciao

    OkkaPapa



  • Makros machen Textersetzung:

    Array = MALLOC (int, AnzahlItems);
    

    wird zu

    Array = {
     (int*)FuncTable->MemAlloc->T_malloc_size_t( (AnzahlItems) * sizeof(int)) 
    };
    

    Und das ist kein gültiges C.
    BTW: Der Cast ist in C unnötig.


  • Mod

    Nathan schrieb:

    BTW: Der Cast ist in C unnötig.

    Das COND_FREE ist auch süß. Da würde ich gerne vom Autor hören, was er denkt, was das macht.



  • SeppJ schrieb:

    Nathan schrieb:

    BTW: Der Cast ist in C unnötig.

    Das COND_FREE ist auch süß. Da würde ich gerne vom Autor hören, was er denkt, was das macht.

    Hmja, meine Doku zur API empfiehlt explizit diese Macros zu verwenden, damit die Speicherallozierung korrekt abläuft.

    Wenn ich das korrekt verstehe, dann wird geprüft, ob der pointer auf einen allozierten Speicher zeigt und wenn ja dann wird der Speicher freigegeben.

    Ciao

    OkkaPapa



  • OkkaPapa schrieb:

    Wenn ich das korrekt verstehe, dann wird geprüft, ob der pointer auf einen allozierten Speicher zeigt und wenn ja dann wird der Speicher freigegeben.

    Wo siehst du eine Abfrage auf allozierten Speicher?

    BTW ich glaube, SeppJ spielt auf die Zuweisung (ptr)=NULL danach an. Die Abfrage ist so generell in Ordnung. Bei free ist die zwar nicht notwendig, aber wer weiß, wie FuncTable->MemAlloc->T_free funktioniert...


  • Mod

    Bashar schrieb:

    BTW ich glaube, SeppJ spielt auf die Zuweisung (ptr)=NULL danach an. Die Abfrage ist so generell in Ordnung. Bei free ist die zwar nicht notwendig, aber wer weiß, wie FuncTable->MemAlloc->T_free funktioniert...

    Eigentlich zielte ich eher auf die Abfrage ab (ein bisschen die Zuweisung aber auch). Und nicht nur aus dem Grund, das eine free-Funktion ohnehin mit Nullzeigern zurecht kommt. Denn was soll hier erreicht werden? Weder wird dieses Ziel erreicht:

    dann wird geprüft, ob der pointer auf einen allozierten Speicher zeigt

    Und selbst wenn dies über die Abfrage festgestellt werden könnte:

    und wenn ja dann wird der Speicher freigegeben.

    Die interessante Frage ist doch: Was, wenn Nein? Hier passiert nichts. Dabei ist dies doch gerade das interessante Szenario. Wozu war die Abfrage dann gut? Fehlerverschleierung?



  • SeppJ schrieb:

    Und nicht nur aus dem Grund, das eine free-Funktion ohnehin mit Nullzeigern zurecht kommt.

    So ein Blödsinn.

    Weder wird dieses Ziel erreicht:

    dann wird geprüft, ob der pointer auf einen allozierten Speicher zeigt

    Das ist nicht das erklärte, sondern das von OkkaPapa vermutete Ziel.



  • SeppJ schrieb:

    Und nicht nur aus dem Grund, das eine free-Funktion ohnehin mit Nullzeigern zurecht kommen sollte.

    FTFY



  • Bashar schrieb:

    SeppJ schrieb:

    Und nicht nur aus dem Grund, das eine free-Funktion ohnehin mit Nullzeigern zurecht kommt.

    So ein Blödsinn.

    Du hast keine Ahnung.
    free kommt mit NULL als Argument zurecht, standardkonform schon seit C89. Noop ist hier dann spezifiziert.

    Die laienhafte Implementierung von

    if(ptr) free(ptr);
    ptr = NULL;
    

    ist Anfängerunsinn.
    Sie nimmt dem vom Compiler generierten Code die Möglichkeit, auf Mehrfachfreigaben desselben Speicherbereiches durch Laufzeit-Exceptions und damit auf Designfehler hinzuweisen (sehr viele Compiler reagieren auf solcherlei Mehrfachfreigaben ungnädig, und das ist auch gut so).
    Auch die Verwendung von uninitialisierten Zeigern wird hiermit zugedeckt (da wiederum die mögliche Exception bei free verhindert wird).



  • Wutz schrieb:

    Bashar schrieb:

    SeppJ schrieb:

    Und nicht nur aus dem Grund, das eine free-Funktion ohnehin mit Nullzeigern zurecht kommt.

    So ein Blödsinn.

    Du hast keine Ahnung.
    free kommt mit NULL als Argument zurecht, standardkonform schon seit C89. Noop ist hier dann spezifiziert.

    Heb dir deine Belehrungen für den Fall auf, dass du mal begriffen hast, wovon überhaupt die Rede ist.


  • Mod

    Bashar, denkst du wirklich, dies wäre irgendwie sinnvoll? Dass dies die eine free-Funktion auf der Welt ist, die nicht mit Nullzeigern zurecht kommt? Dass der Autor des Makros wirklich einen guten Grund hatte, auf Null zu prüfen? Dass dies nicht irgendein Cargo-Cult-Makro ist, das der Autor irgendwo abgeschrieben hat, ohne es zu verstehen?



  • SeppJ schrieb:

    Bashar, denkst du wirklich, dies wäre irgendwie sinnvoll?

    Vielleicht, vielleicht nicht, mutmaßen kann man immer, der Punkt ist: Du weißt es nicht.

    Dass dies die eine free-Funktion auf der Welt ist, die nicht mit Nullzeigern zurecht kommt?

    Dieses Verhalten ist doch nicht naturgegeben, in free steht vorne auch bloß ein if (p != NULL) drin, ansonsten wäre die erste Aktion ein Zugriff auf vermeintliche Chunk-Daten bei NULL-x. Ich kenne ansonsten nicht soviele free-Funktionen, schon gar nicht kenne ich Statistiken darüber, wie die genau funktionieren.

    Dass der Autor des Makros wirklich einen guten Grund hatte, auf Null zu prüfen?

    Hmja, meine Doku zur API empfiehlt explizit diese Macros zu verwenden, damit die Speicherallozierung korrekt abläuft.

    Sieht so aus, als wüsste der Autor dieses Makros mehr über die API (und ihre free-Funktion) als wir.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    Bashar, denkst du wirklich, dies wäre irgendwie sinnvoll?

    Vielleicht, vielleicht nicht, mutmaßen kann man immer, der Punkt ist: Du weißt es nicht.

    Man kann aber aus früheren Erfahrungen extrapolieren. Wie viele Makros dieser Art hast du schon gesehen? Dutzende? Wie viele davon beruhen darauf, dass der Autor keine Ahnung hatte? Alle? Ist es wahrscheinlich, dass dieser Fall hier die Ausnahme ist oder ein weiterer Fall von Unwissen, auf den man den TE hinweisen sollte?



  • SeppJ schrieb:

    Wie viele davon beruhen darauf, dass der Autor keine Ahnung hatte? Alle?

    Ja. Gut gedacht, aber Doku nicht gelesen.

    Ist es wahrscheinlich, dass dieser Fall hier die Ausnahme ist oder ein weiterer Fall von Unwissen, auf den man den TE hinweisen sollte?

    Mal abgesehen davon, dass du dich nur darüber lustig gemacht hast: Worauf genau würdest du ihn denn hinweisen wollen? Dass er die Doku zu der API lesen soll? Hat er gemacht, das Zitat findest du inzwischen schon zweimal in diesem Thread.



  • SeppJ schrieb:

    Nathan schrieb:

    BTW: Der Cast ist in C unnötig.

    Das COND_FREE ist auch süß. Da würde ich gerne vom Autor hören, was er denkt, was das macht.

    UND

    Bashar schrieb:

    SeppJ schrieb:

    Wie viele davon beruhen darauf, dass der Autor keine Ahnung hatte? Alle?

    Ja. Gut gedacht, aber Doku nicht gelesen.

    Das ist dann der Autor der API.
    Würde auch gerne vom Autor hören, was er sich dabei gedacht hatte.



  • volkard schrieb:

    Das ist dann der Autor der API.

    Nein, der Autor des Makros.



  • OkkaPapa schrieb:

    SeppJ schrieb:

    Nathan schrieb:

    BTW: Der Cast ist in C unnötig.

    Das COND_FREE ist auch süß. Da würde ich gerne vom Autor hören, was er denkt, was das macht.

    Hmja, meine Doku zur API empfiehlt explizit diese Macros zu verwenden, damit die Speicherallozierung korrekt abläuft.

    Dann hat doch der Autor der API das Makro erfunden (ist dessen Autor) und empfiehlt es. Es passt schnuckelig gut zur API, sagt er.



  • OK, aber man kann ihm nicht vorwerfen, die Doku nicht gelesen zu haben.



  • Bashar schrieb:

    OK, aber man kann ihm nicht vorwerfen, die Doku nicht gelesen zu haben.

    Das stimmt.

    OkkaPapa hat sich nichts vorzuwerfen.

    Es kann sein, daß die API dazu lustige Sachen vorschlägt, die voll harmonisch dazupassen. In größeren Funktionen mit etlichen allokierten Variablen zum Beispiel

    #define RETURN(x) ret=x;goto finalize;
    

    um sich vom Single-Exit-Dogma der Strukturierten Programmierung lösen zu können. Das wissen wir nicht. Kann sein.

    Nu mag SeppJ aber schon erzählen, was er so weiß, es ist viel, es ist wertvoll, man sollte ihm lauschen. Und ich wette meinen Schuh drauf, daß er auch richtig geraten hat, der Autor des Makros ist Nube.
    Denn es verdeckt Programmierfehler. Je später sie gefunden werden, desto teurer sind sie. Das geht von einem

    0x...c5 bei msvc, zack, Debugger ist schon an auf der richtigen Codezeile, ich meinte doch *i und nicht *j, was da natürlich ==0 hat, 10 Sekunden,

    über verflixt, assert(!is_sortet(cont)) flog, das kann nicht sein, ich werde es herausfinden,

    bis zu einem, und das ist traurig und typisch, mein lokaler Energieversorger hat sich ein neues Programm bauen lassen, hoffnungsfroh umgestellt, es klappte nicht, sie haben 9 Monate keine Rechnungen stellen können, an der Grasnabe vorbei dem Konkurs davongeschlittert.

    Je später, desto umso umso umso teurer. Man verbirgt keine Fehler.

    Der lokale Versorger war vorher granatengeil. Immer fehlerfrei, perfekte Beratung (Telekom sagte dazumal "Unser Internet ist virenfrei"), fast halb so teuer wie Telekom und mehr Leistung. Wachstum wie wild, klar. Nach dem Datenbank-Debakel war es um. Die Preise zogen rapide an bis supi dicht unter Telekom, es wurden in den Vorstand Schwätzer gezogen, man kann Freunden nicht mehr sagen, daß sie hinwechseln sollten. Der Aufwand des Wechselns ist es nicht wert.



  • Hallo!

    Möchte auch gern mitflamen 🙂
    Ich habe nach langem betteln von de Kollegen, die die API machen eine Doku bekommen wo es so drinsteht.

    Vorher hatte ich nur ne Latte Headerdateien,die zu 90% dokumentiert waren, teilweise auch noch falsch...

    Lange Rede, kurzer Sinn: ich weiß nicht, was das für einen Sinn hat und gebe zu, daß ich so tief in den Feinheiten von free nicht drinstecke.
    Ich tu so wir mir gesagt und wenns im Speicher rummst kann ich wenigstens sagen, daß ich mich an die API-Doku gehalten habe und kriege Hilfe.

    Und meine eigentliche Frage mit den Makros wurde ja beantwortet.

    Danke dafür!!!

    Ciao

    OkkaPapa


Log in to reply