Arrayinitialisierung nur per define möglich



  • moagnus schrieb:

    Jedoch werden mit const sehr wohl "echte" Konstanten erzeugt,

    nur mit glück, wenn sie in einen speicherbereich kommen, der physikalisch schreibgeschützt ist.

    Kannst du das vllt. mal ein bisschen ausführen?

    auf einem microcontroller z.b. landen const-objekte z.b. oft im flash. das ist ein speicher, der zwar einfach gelesen, aber nicht 'auf normalem' wege beschrieben werden kann. schreibzugriffe haben dort entweder gar keine wirkung, oder lösen eine exception aus.
    übrigens sind solche 'gespeicherten' konstanten nur als array, structs oder funktionen interessant. einzelne, konstante integers, chars, etc. irgendwo gespeichert zu haben, hat selten einen vorteil. oft ist ein schlichtes #define nützlicher.
    🙂



  • Amen! ^^



  • Mein Compiler (gcc 4.1)

    Nicht konstant ist n im Sinne von "Konstant zur Kompilierungszeit".

    Ok. Und durch die Präprozessorersetzung bei "#define SIZE 5" ist eine Angabe mit SIZE bereits zur Kompilierungszeit konstant, ja?

    @fricky: Bleiben halt noch die unschönen "Nebenwirkungen" von #define... Bzw. man benutzt die Lösung von Big Brother/ruediger. Damit erhält man ja auch ne "Konstante".



  • moagnus schrieb:

    Mein Compiler (gcc 4.1)

    Der muss -std=c99 kennen.



  • Sorry, keine Ahnung, was ich vorhin für nen Blödsinn gemacht hab. Das Flag wird jetzt akzeptiert, das Problem dadurch aber leider nicht behoben.



  • moagnus schrieb:

    @fricky: Bleiben halt noch die unschönen "Nebenwirkungen" von #define... Bzw. man benutzt die Lösung von Big Brother/ruediger. Damit erhält man ja auch ne "Konstante".

    naja, so'n define als konstante ist harmlos. unschöne nebenwirkungen haben nur function-like makros, aber die sind auch überschaubar. aber klar, enums sind auch prima konstanten.
    🙂



  • fricky schrieb:

    moagnus schrieb:

    Jedoch werden mit const sehr wohl "echte" Konstanten erzeugt,

    nur mit glück, wenn sie in einen speicherbereich kommen, der physikalisch schreibgeschützt ist.

    Kannst du das vllt. mal ein bisschen ausführen?

    auf einem microcontroller z.b. landen const-objekte z.b. oft im flash. das ist ein speicher, der zwar einfach gelesen, aber nicht 'auf normalem' wege beschrieben werden kann. schreibzugriffe haben dort entweder gar keine wirkung, oder lösen eine exception aus.
    übrigens sind solche 'gespeicherten' konstanten nur als array, structs oder funktionen interessant. einzelne, konstante integers, chars, etc. irgendwo gespeichert zu haben, hat selten einen vorteil. oft ist ein schlichtes #define nützlicher.
    🙂

    Ähem, und die Define-Literale müssen nirgends gespeichert werden? Wo soll das Programm seine Werte denn herzaubern? Aus dem Silizum brechen?



  • Was spricht gegen

    char *p = "huhu";
    

    oder

    char p[] = "haha";
    

    ?

    Der Compiler weiß doch wie lange der String ist.



  • Bei #define SIZE 5 ersetzt der Preprozessor wie gesagt die entsprechenden Stellen (SIZE durch 5), die 5 taucht im Code der "EXE" und damit auch im Arbeitsspeicher (bei Ausführung) nicht auf. Das Array wird die Länge 5 haben und fertig. Andernfalls (nicht #define) ist die Länge ebenfalls klar, aber die 5 ist zusätzlich und völlig unnütz auch noch im Code und bei Ausführung im ProcessMemory oder wo auch immer vorhanden.



  • #define BUFF_SIZE 128
    unsigned char buf[BUFF_SIZE];
    
    FILE* fid = fopen("pups.dat", "rb");
    /*...*/
    while(!feof(fid))
    {
        fread(buf, sizeof(buf), 1, fid);
        /*process buf*/
    }
    fclose(fid);
    

    PS: Es gibt noch was anderes, als String-Literale...



  • dust schrieb:

    Bei #define SIZE 5 ersetzt der Preprozessor wie gesagt die entsprechenden Stellen (SIZE durch 5), die 5 taucht im Code der "EXE" und damit auch im Arbeitsspeicher (bei Ausführung) nicht auf. Das Array wird die Länge 5 haben und fertig. Andernfalls (nicht #define) ist die Länge ebenfalls klar, aber die 5 ist zusätzlich und völlig unnütz auch noch im Code und bei Ausführung im ProcessMemory oder wo auch immer vorhanden.

    Ehem, und dann kommt im Code ja noch meist sowas:

    int cnt;
    for(cnt = 0; cnt < SIZE; ++cnt)
    {
        /*...*/
    }
    

    So, und was passiert? Richtig. SIZE wird durch den Wert 5 ersetzt. Und diese 5 wird zu einem Bestandteil Deines Kompilates und steht irgendwo im Speicher. Oder wo soll er die Deiner Meinung nach her nehmen? Zur Laufzeit gibts keinen Präprozessor. 😉



  • RICHTIG, da steht der WERT 5, aber eben NUR dort und nicht noch am arsch irgendwo ... einmal weniger halt ... 😉

    EDIT: GO 4 Seite5 ^^



  • char *p="12345";
    

    funzt,

    char p[4] = "123456";
    

    haut Dir das Programm zusammen bzw. ergibt schwer zu findende Probleme.

    Ob da eine "4" oder eine Konstante per #define drinne steht ist egal.
    Der Präprozessor ersetzt im Quelltext und nicht zur Laufzeit.

    [code]#define HEPP 4
    char p[HEPP] ="...";[quote]

    ist absolut identisch mit

    [code]char p[4] ="...";[quote]



  • dust schrieb:

    RICHTIG, da steht der WERT 5, aber eben NUR dort und nicht noch am ***** irgendwo ... einmal weniger halt ... 😉

    EDIT: GO 4 Seite5 ^^

    😕



  • OK, es besteht die Möglichkeit, dass ich falsch liege, aber ist es nicht so, dass bei einer nicht durch "#define" definierten Konstante der Wert (hier:5) einmal sinnlos irgendwo im Code (bei Code rede ich vom "Maschinencode" oder meinetwegen auch von Assembler) steht? Und genau dieses eine mal ist halt mehr als bei #define ... ist immernoch net klar, was ich meine? Als nächstes mal ich ein Bild .. xD ..



  • dust schrieb:

    OK, es besteht die Möglichkeit, dass ich falsch liege, aber ist es nicht so, dass bei einer nicht durch "#define" definierten Konstante der Wert (hier:5) einmal sinnlos irgendwo im Code (bei Code rede ich vom "Maschinencode" oder meinetwegen auch von Assembler) steht? Und genau dieses eine mal ist halt mehr als bei #define ... ist immernoch net klar, was ich meine? Als nächstes mal ich ein Bild .. xD ..

    Falsch.
    Wenn man einen Gammel-Compiler hat, und ein DEFINE an N Stellen benutzt, dann bekommt man dadurch N Ersetzungen und der ersetzte Wert wird N mal in den Maschinencode gepackt.
    Ein const hingegen steht an einer dedizierten Speicherzelle und muss so nur einmal vorhanden sein. Gute Compiler sollten aber Defines auch dahin gehend auflösen können (glaube ich, bin mir nicht sicher).



  • Aber einen Wert reinzupacken (auch, wenn es N mal ist) ist noch immernoch effizienter und weniger aufwändig, als jedesmal eine Adresse reinzupacken, die dann jedesmal angesprungen werden muss. Das meine ich, und ich denke jetzt versteht es auch jeder.



  • Tachyon schrieb:

    Ehem, und dann kommt im Code ja noch meist sowas:

    int cnt;
    for(cnt = 0; cnt < SIZE; ++cnt)
    {
        /*...*/
    }
    

    So, und was passiert? Richtig. SIZE wird durch den Wert 5 ersetzt. Und diese 5 wird zu einem Bestandteil Deines Kompilates und steht irgendwo im Speicher. Oder wo soll er die Deiner Meinung nach her nehmen? Zur Laufzeit gibts keinen Präprozessor. 😉

    nicht zwansgläufig. Manche Optimierungsstufen wie -funroll-loops können dazu führen, dass der Inhalt der for-Schleife eben 5 Mal hintereinander vorkommt. Dann muss im Code keine 5 für die Abbruchbedingung auftauchen 😉

    Um ehrlich zu sein, verstehe ich gar nicht mehr, worüber ihr euch letzendlich streitet. Ein #define ist eine reine Textersetzung vor der Compilieren. Ob die integralen Konsanten hinter dem define vom Compiler zur echten Konstanten werden oder nicht, hängt ihmo vom Kontext ab, wo das Makro auftaucht (und eben welche Optimierungsstufe man wählt).

    Tachyon schrieb:

    Gute Compiler sollten aber Defines auch dahin gehend auflösen können (glaube ich, bin mir nicht sicher).

    was soll das genau heißen? 😕



  • Streiten würd ich das jetzt nicht nennen, wir sind ja friedlich und wollen am Ende nur mit bestem Wissen und Gewissen aus der Diskussion rausgehen. Ich hab' schonwieder ein bisschen dazu gelernt, und am Ende werde ich genau wissen, wann ich welche Konstante (bzw. Konstantendefinition) weswegen nehmen kann und nehmen sollte, darum gehts. 👍



  • dust schrieb:

    Bei #define SIZE 5 ersetzt der Preprozessor wie gesagt die entsprechenden Stellen (SIZE durch 5), die 5 taucht im Code der "EXE" und damit auch im Arbeitsspeicher (bei Ausführung) nicht auf. Das Array wird die Länge 5 haben und fertig. Andernfalls (nicht #define) ist die Länge ebenfalls klar, aber die 5 ist zusätzlich und völlig unnütz auch noch im Code und bei Ausführung im ProcessMemory oder wo auch immer vorhanden.

    Natürlich kommt die 5 irgend wo vor. Immerhin muss der Speicher ja nach bereit gestellt werden und dazu sollte man die Länge wissen.


Anmelden zum Antworten