Arrayinitialisierung nur per define möglich



  • 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 */
    


  • Tachyon schrieb:

    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?*/
    

    Klar belegen sie Speicherplatz der Festplatte. Schau mal was daraus nach dem Kompilieren passiert.
    Dann weißt du auch ob sie dann immer noch Speicherplatz der Festplatte belegen.

    Binary != Speicherverbrauch bei der Ausführung.



  • LordJaxom schrieb:

    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 */
    

    Und wo kommt in Deinem kompilierten Binary dieser Wert her? Der Wert (die 0) steht im Binary. Wird das Programm geladen, steht es im Speicher und der Wert nimmt entsprechend den Platz weg.



  • ja, aber fuer test_enum geht unnötig Platz drauf (nicht, dass das schlimm wär, aber besser ist den Platz nicht zu brauchen)



  • Tachyon schrieb:

    Und wo kommt in Deinem kompilierten Binary dieser Wert her? Der Wert (die 0) steht im Binary. Wird das Programm geladen, steht es im Speicher und der Wert nimmt entsprechend den Platz weg. Bei einer Plattform mit Harvard-Architektur würde der Wert konkret an der Codestelle im Programmspeicher stehen.

    Teilst Du uns gerade das offensichtliche mit oder willst Du im Ernst darauf hinaus, das sei bei einem define anders?



  • Das ist eine Diskusion um des Kaisers Bart..

    Man sollte seinen Code nicht nach "Vorteilen" wählen sondern nach "Nachteilen".
    -->um sie zu kennen und auszuschließen bzw. damit zu arbeiten.

    Es ist doch die Frage was will ich und brauche ich...

    Imho statement



  • #define für sowas verwenden und gut finden...

    ich packs einfach nicht.

    wenn ich von etwas nicht die adresse nehme, dann muss es auch keine adresse haben.



  • Tachyon schrieb:

    Und wo kommt in Deinem kompilierten Binary dieser Wert her? Der Wert (die 0) steht im Binary. Wird das Programm geladen, steht es im Speicher und der Wert nimmt entsprechend den Platz weg.

    Dust bezieht sich wohl eher auf eine Speicherstelle, die die Konstante geschrieben wird und dann vor dem Anlegen noch einmal aus dieser Speicherstelle gelesen werden muss.

    Und wenn du einfach nur ein enum-Literal definierst und nicht benutzt, wirst du den Wert auch nicht im Binary finden.

    dust schrieb:

    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").

    Mit Grundlagen meine ich in dem Fall die Sprachfeatures (Schlüsselwörter etc.). Egal was irgend ein Buch über C++ dazu sagt.

    Und bei enums muss man natürlich unterscheiden. Ich bezog mich auf enum Literale.

    enum a {
      A = 1 // <- "enum Literal"
    };
    
    enum a b; // <- "enum Variable"
    

    Das größte Problem bei define ist übrigens die Namensraum Verunreinigung. Das merkt man schnell, wenn man schlecht geschriebene Libraries einbindet. Ein großer Hersteller hat in einem viel zu großen Header zB ein define auf so etwas ausgefallenes wie far oder near gelegt. Du kannst dir ja denken, was dann passiert.

    Da enums ein Sprachfeature (und kein CPP Feature) sind, unterliegen sie auch Sichtbarkeitsbereichen.

    #include <stdio.h>
    
    enum { N = 10 };
    
    void foo() {
      printf("%d\n", N);
    }
    
    void bar() {
      enum { N = 100 };
      printf("%d\n", N);
    }
    
    int main() {
      enum { N = 2 };
      printf("%d\n", N);
      foo();
      bar();
    }
    

    Ich hoffe, dass dir das Problem nun einigermaßen klar geworden ist. (wenn nicht, ersetz mal das enum durch ein #define). Das Problem tritt natürlich unabhängig davon auf, was man hinter das #define setzt.

    dust schrieb:

    ja, aber fuer test_enum geht unnötig Platz drauf (nicht, dass das schlimm wär, aber besser ist den Platz nicht zu brauchen)

    Nein. Meinst du vielleicht enum_test ? Das ist ja ein Beispiel, was ganz unabhängig von der Verwendung eines enum Literals für Arraylängen ist.



  • enum { N = 100 };
    char arr [N];

    Hab's jetzt, denke ich. Ich fass mal zusammen:

    Durch enum {N = 100} wird eine "echte" Konstante erzeugt, nämlich N. Dennoch wird, wie bei der Benutzung von #define, kein zusätzlicher Speicherplatz gebraucht, d.h. die 100 taucht nirgendwo als gespeicherter Wert auf, wie das bei einer Variable der Fall wäre. Zusätzlich merkt der Compiler sofort, wenn unsere Konstante kein Integer ist. Die perfekte Lösung!? Richtig so?

    Werd das zukünftig so machen, anstatt mit #define.



  • rüdiger schrieb:

    [letzter Post...]

    Jo, danke. Du bringst das so recht gut auf den Punkt. So meinte ich das. 👍

    In C++ kann man enums allerdings in Namespaces packen, um die Sichtbarkeit einzuschränken. Mit defines geht das nicht.



  • Das kommt noch dazu. Schwere Geburt, aber das Kind ist da.



  • #define SIZE 5
    int main() {
    	//const unsigned int SIZE = 5;
    	char string[SIZE] = "Test";
    	return 0;
    }
    

    Um noch mal auf's Thema zu kommen:

    Er definiert die Stringlänge gleich 2mal, einmal durch SIZE und dann durch
    die Initialisierung des Strings. Es gibt nur recht wenige Spezialfälle wo so
    etwas Sinn machen könnte.

    Nach enums hat kein Mensch gefragt.

    Nastatt das ihr ihm Sinn oder Unsinn erklärt haut ihr euch gegenseitig wirres
    Zeugs um die Ohren. Ich denke, der Erstposter hat da elementarere Probleme.


Anmelden zum Antworten