Arrayinitialisierung nur per define möglich



  • #define bzw. Makros sind recht praktisch, auch Sachen wie __DATE__, __TIME__,
    __FILE__ etc. Auch kann man mit #define den Code lesbarer machen (wen Du's nicht
    glaubst schau Dir ein Programm an was Du vor 5 Jahren verzapft hast :)).



  • Irgendwie finde ich die Diskussion über die Ablage von Integerliteralen sowieso reichlich merkwürdig.

    // nur ein Beispiel
    #define BLOCK_SIZE 44100 * sizeof(int)
    
    for (int i = 0; i < BLOCK_SIZE; ++i) {
    }
    

    Da wird der Compiler sowas draus machen:

    ...
    cmp [irgendwas], 176400
    ...
    

    Wo seht ihr (bzw. Tachyon) jetzt bitte das Potential, diese 176400 "nur einmal" ins Binary zu packen?



  • Tachyon schrieb:

    Und ich weiss nicht, ich finde, man produziert mit Defines ziemlich schnell überflüssigen Overhead:

    Welchen Overhead meinst du? Die falschen Kommentare werden vom Preprozessor entfernt, falls du das meinst...



  • LordJaxom schrieb:

    Irgendwie finde ich die Diskussion über die Ablage von Integerliteralen sowieso reichlich merkwürdig.

    // nur ein Beispiel
    #define BLOCK_SIZE 44100 * sizeof(int)
    
    for (int i = 0; i < BLOCK_SIZE; ++i) {
    }
    

    Da wird der Compiler sowas draus machen:

    ...
    cmp [irgendwas], 176400
    ...
    

    Wo seht ihr (bzw. Tachyon) jetzt bitte das Potential, diese 176400 "nur einmal" ins Binary zu packen?

    das ist genau was ich 2 Seiten davor meinte. Außerdem kann der Compiler z.B. Schleifen wegoptimieren und den Code mehrmals hintereinander schreiben.



  • LordJaxom schrieb:

    Irgendwie finde ich die Diskussion über die Ablage von Integerliteralen sowieso reichlich merkwürdig.

    [cpp]
    // nur ein Beispiel
    #define BLOCK_SIZE 44100 * sizeof(int)

    Das ist kein Literal...

    EDIT: Das Lookup funktioniert wohl nur bei String-Literalen. Bei numerischen Literalen wird einfach ersetzt.



  • supertux schrieb:

    das ist genau was ich 2 Seiten davor meinte. Außerdem kann der Compiler z.B. Schleifen wegoptimieren und den Code mehrmals hintereinander schreiben.

    Loop-Unwinding funktioniert aber nur bei For-Schleifen, bei denen zur Compilezeit die Abbruchbedingung klar ist.
    Sobald Du andere Konstruktionen hast, geht das nicht mehr:

    while expression 
        ...
        if some_value >= DEFINE_MACRO then
            modify expression;
        [u]fi[/u]
        ...
    [u]elihw[/u]
    


  • Erinnert euch mal daran, dass ich die Diskussion mit diesem Statement:

    Btw. spricht in diesem Fall (array length) NIX gegen die Benutzung von #define.

    losgetreten habe.

    Und ich denke, dass hat sich bewahrheitet und wir sollten evtl. langsam abschließen. Die Nachteile von #define können ausgeschlossen werden, sodass nur noch die Vorteile da sind.



  • dust schrieb:

    Erinnert euch mal daran, dass ich die Diskussion mit diesem Statement:

    Btw. spricht in diesem Fall (array length) NIX gegen die Benutzung von #define.

    losgetreten habe.

    Und ich denke, dass hat sich bewahrheitet und wir sollten evtl. langsam abschließen.

    Es hat sich nicht bewahrheitet. Es spricht immer noch das gleiche dagegen, wie bei jeder anderen Benutzung von #define. Warum sollten Arraylängen hier anders behandelt werden, als andere Fälle?



  • Weil Array-Längen nunmal todessimpel sind. Gegen #define IN DIESEM FALL spricht alleine, dass der Compiler den Typ nicht kennt, was aber total wayne ist, weil niemand auf die Idee kommt da was anderes als nen Element aus N+ hinter zu klemmen, somit bleiben nur noch die Vorteile, die ja (siehe oben) ausreichend beleuchtet wurden. Wie kann man das nicht einsehen?



  • dust schrieb:

    Weil Array-Längen nunmal todessimpel sind. Gegen #define IN DIESEM FALL spricht alleine, dass der Compiler den Typ nicht kennt, was aber total wayne ist, weil niemand auf die Idee kommt da was anderes als nen Element aus N+ hinter zu klemmen, somit bleiben nur noch die Vorteile, die ja (siehe oben) ausreichend beleuchtet wurden. Wie kann man das nicht einsehen?

    Was spricht nach deiner Meinung gegen die Verwendung von define in anderen Fällen?

    Die Nachteile von define sind imho unabhängig von dem was man damit definiert. Der CPP macht ja auch keinen Unterschied.

    Und warum nicht einfach enum benutzen, damit wird man die Nachteile von define in dem Fall elegant los?



  • Dein Nachteil ist bei mir einfach kein Nachteil, ganz einfach ... aus dem genannten Grund. Es ist trivial, total simpel, das ist unvermurksbar. Enum zu benutzen ist doch im Endeffekt nichts Anderes als 'ne Konstante mit const zu definieren (vorausgesetzt der Compiler meckert nicht, wenn man die Konstante dann als array length nimmt)... man hat halt einmal unnütz den Wert im Speicher, der angesprungen wird, anstatt einfach gleich den Wert selbst zu nehmen (mal abgesehen von mehr oder weniger wilden Spekulationen über diese und jene Optimierung die eventuell von dem und dem Compiler vorgenommen wird).

    EDIT: Ich seh schon, wir schaffen die 8 Seiten (omg).



  • dust schrieb:

    Enum zu benutzen ist doch im Endeffekt nichts Anderes als 'ne Konstante mit const zu definieren (vorausgesetzt der Compiler meckert nicht, wenn man die Konstante dann als array length nimmt)...

    Stimmt so nicht. Enum-Konstanten sind "echte" Konstanten (im Sinne dieser Diskussion) und können _immer_ als Arraygrenzen verwendet werden, sogar in C89.



  • dust schrieb:

    Dein Nachteil ist bei mir einfach kein Nachteil, ganz einfach ... aus dem genannten Grund. Es ist trivial, total simpel, das ist unvermurksbar.

    Also gibt es keinen Nachteil bei jeglicher Benutzung von define nach deiner Meinung? (Wenn doch, dann nenn mir doch bitte die Nachteile nach deiner Meinung).

    Enum zu benutzen ist doch im Endeffekt nichts Anderes als 'ne Konstante mit const zu definieren (vorausgesetzt der Compiler meckert nicht, wenn man die Konstante dann als array length nimmt)... man hat halt einmal unnütz den Wert im Speicher, der angesprungen wird, anstatt einfach gleich den Wert selbst zu nehmen (mal abgesehen von mehr oder weniger wilden Spekulationen über diese und jene Optimierung die eventuell von dem und dem Compiler vorgenommen wird).

    Worauf basiert deine Spekulation? Enums belegen natürlich keinen Speicher.



  • Dein Nachteil ist bei mir einfach kein Nachteil, ganz einfach ... aus dem genannten Grund. Es ist trivial, total simpel, das ist unvermurksbar.

    Also gibt es keinen Nachteil bei jeglicher Benutzung von define nach deiner Meinung? (Wenn doch, dann nenn mir doch bitte die Nachteile nach deiner Meinung).

    Nein, wie gesagt ... es ist nur in DIESEM FALL kein wirklicher Nachteil. Nicht generell. Zur Erinnerung, es geht um den "Nachteil", dass der Compiler den Typ nicht kennt/überprüfen kann.

    Enum zu benutzen ist doch im Endeffekt nichts Anderes als 'ne Konstante mit const zu definieren (vorausgesetzt der Compiler meckert nicht, wenn man die Konstante dann als array length nimmt)... man hat halt einmal unnütz den Wert im Speicher, der angesprungen wird, anstatt einfach gleich den Wert selbst zu nehmen (mal abgesehen von mehr oder weniger wilden Spekulationen über diese und jene Optimierung die eventuell von dem und dem Compiler vorgenommen wird).

    Worauf basiert deine Spekulation? Enums belegen natürlich keinen Speicher.

    Das war reine Intuition, bitte erklär mir, wie das mit enum läuft. Wenn es keinen Speicher belegt, dann werden wir in Zukunft alle diese Variante benutzen und haben gar keinen Nachteil mehr.



  • dust schrieb:

    Das war reine Intuition, bitte erklär mir, wie das mit enum läuft. Wenn es keinen Speicher belegt, dann werden wir in Zukunft alle diese Variante benutzen und haben gar keinen Nachteil mehr.

    Enums sind keine Variablen, sondern "echte" Konstanten. Befass dich vielleicht ein bisschen mit den Grundlagen 🙄.



  • Enums sind keine Variablen, sondern "echte" Konstanten. Befass dich vielleicht ein bisschen mit den Grundlagen.

    Und warum sagst du das nicht gleich? Btw. gehört das nicht zu den Grundlagen, zumindest nicht in meinen Büchern. Da habe ich es gerade unter Erweiterte Typen gefunden, etliche Kapitel hinter Grundlagen. Und dort steht, dass enums sehr wohl Variablen sind ("C++ Objektorientiertes Programmieren von Anfang an").


  • Mod

    dust schrieb:

    Zur Erinnerung, es geht um den "Nachteil", dass der Compiler den Typ nicht kennt/überprüfen kann.

    Wer dieses Gerücht wohl in die Welt gesetzt hat... - und völlig unnötig: #define sind oft genug nicht die beste Lösung, da braucht man nicht noch etwas dazu erfinden.



  • rüdiger schrieb:

    dust schrieb:

    Das war reine Intuition, bitte erklär mir, wie das mit enum läuft. Wenn es keinen Speicher belegt, dann werden wir in Zukunft alle diese Variante benutzen und haben gar keinen Nachteil mehr.

    Enums sind keine Variablen, sondern "echte" Konstanten. Befass dich vielleicht ein bisschen mit den Grundlagen 🙄.

    Ich frage nochmal: Wo sollen die Werte für die Konstanten her kommen, wenn sie keinen Speicher im Binary belegen?

    typedef enum
    {
       A = 0,
       B = 1,
       C = 2,
       D = 4
    } test_enum;
    
    /*...*/
    
    test_enum enum_test = A; /*Woher kommt der Wert den A repräsentiert? Aus der Luft?*/
    


  • Ich habe in einem weiteren Buch nachgeschlagen, dort steht ebenfalls, dass mit enum zwar Konstanten erzeugt werden, aber trotzdem für den Bezeichner (wenn man das hier so nennen will/darf) Platz benötigt wird, und so dachte ich das auch. Also doch #define, ich bleib dabei .. in DIESEM Fall die beste Lösung.



  • Tachyon schrieb:

    test_enum enum_test = A; /*Woher kommt der Wert den A repräsentiert? Aus der Luft?*/
    

    Nochmal: Der Compiler setzt hier den Wert für A literal ein. In etwa so:

    mov [ebp+xx], 0 /* <- das da ist A */
    

Anmelden zum Antworten