Arrayinitialisierung nur per define möglich



  • fricky schrieb:

    Scheppertreiber schrieb:

    Nein, ein #define ist nichts anderes wie ein Text, dieser wird anstelle des
    Namens direkt in den Programmtext eingesetzt.

    richtig! aber genau das ist machmal ein vorteil.
    🙂

    Aber ja. Da soll der Compiler ja auch nichts optimieren.
    So ein #ifdef DEBUG ist äußerst praktisch ... 🙂



  • Scheppertreiber schrieb:

    fricky schrieb:

    Scheppertreiber schrieb:

    Nein, ein #define ist nichts anderes wie ein Text, dieser wird anstelle des
    Namens direkt in den Programmtext eingesetzt.

    richtig! aber genau das ist machmal ein vorteil.
    🙂

    Aber ja. Da soll der Compiler ja auch nichts optimieren.

    wie sollen ihn #defines am optimieren hindern?
    🙂



  • Der Compiler selbst dürfte ein #define nicht sehen. #define gehört nicht zum
    Sprachumfang, genau wie #include etc. Es sind Anweisungen für den Präprozessor.

    Was er nicht sieht kann er nicht optimieren.



  • Scheppertreiber schrieb:

    Der Compiler selbst dürfte ein #define nicht sehen...
    Was er nicht sieht kann er nicht optimieren.

    er sieht aber den quelltext, auf den #defines direkte auswirkungen haben.
    beispiel:

    #define HELLOTEXT "hello, world!"
    ...
    char *a = HELLOTEXT;
    char *b = HELLOTEXT;
    char *c = HELLOTEXT;
    

    der compiler kann 'string pooling' anwenden, damit der initialisierer nur einmal im binary vorkommt.
    🙂



  • Klar.

    Würde ich so etwas in einem PIC8 verwenden würde ich auch viel Wert drauf legen 🙂
    Für Windows ist das wurscht, da wird soviel mit Ressourcen geaast, da kommt's auf
    die Paar Bytes nicht an.

    In Deinem Beispiel würde ich das von Haus aus schon so definieren:

    char *p = "Hallo bin auch da";

    printf( "\n%s", p);
    printf( "\n%s", p);
    ...



  • Scheppertreiber schrieb:

    Würde ich so etwas in einem PIC8 verwenden würde ich auch viel Wert drauf legen 🙂
    Für Windows ist das wurscht, da wird soviel mit Ressourcen geaast, da kommt's auf
    die Paar Bytes nicht an.

    deswegen nimmt unter windows heute noch kaum jemand C. dafür gibt's ja .NET und ähnliches. aber da, wo C oft verwendet wird, ist auch sehr oft resourcensparendes programmieren angesagt.
    🙂



  • Es hat Gründe warum ich bei C bleibe:

    Ich habe eine wilde Mischung aus CGI- Kommandozeilen und Windowsprogrammen (da
    zum Glück aber nur wenige). Ich plane, das (wenn ich mal Zeit habe) auf Linux zu
    portieren. Versuche habe ich gemacht, geht relativ problemlos.

    NET etc. werde ich nicht verwenden. Ich bin dann auch wieder zu Updates gezwungen
    und das hänge ich mir nicht mehr ans Bein.

    C ist schnell, extrem flexibel und ich kann große System draus bauen. Der ++Overhead
    erinnert mich zu stark an Deutsche Verwaltung und bringt mir nichts.



  • Scheppertreiber schrieb:

    C ist schnell, extrem flexibel und ich kann große System draus bauen.

    da hast du recht, aber das bauen von grossen systemen ist in C verdammt aufwendig und fehleranfällig, bereits eine kleine windows-anwendung mit fensterchen oder dialogboxen und graphischen controls usw. würde ich nicht in C machen wollen (auch wenn's dafür libraries wie GTK u.ä. gibt).

    Scheppertreiber schrieb:

    Der ++Overhead erinnert mich zu stark an Deutsche Verwaltung und bringt mir nichts.

    meinst du C++? ja, das sind wir einer meinung. C++ finde ich auch total schrottig.
    🙂



  • Ok, fehleranfällig war C schon immer ...

    Beim Bauen größerer Systeme gibt es so ganz einfache Regeln:

    * keine Funktion größer wie der Bildschirm
    * Strukturen verwenden
    * immer wiederverwendbare Sachen in libs auslagern

    dann geht's.

    Ich mache nur recht wenige Win-Programme, die meisten sind HTML-Generatoren
    und Kommandozeilenprogramme. Wenn's um größere Datenmengen geht ist C nicht zu
    toppen.

    (Im Moment ein Archivsystem über's Web, die Windows-Programme sind standalone
    Dinger für die Kunden).



  • supertux schrieb:

    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? 😕

    Das soll heissen, dass es wohl Compiler gibt die es erkennen, wenn ein gleiches Literal an verschiedenen Stellen benutzt wird, und dieses Literal dann nur einmal in das Binary packen. Wird das Literal dann benutzt, wird es über eine Lookup-Tabelle herangezogen.

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

    #define SAMPLE_RATE 44100    //samplerate
    #define BLOCK_LENGTH_S 0.5f   //length of one block in s
    #define BLOCK_LENGTH ((int)(SAMPLE_RATE * BLOCK_LENGTH_S))
    #define BUFFER_SIZE (10 * BLOCK_LENGTH)
    
    /*...*/
    
    float buffer[BUFFER_SIZE]; /*-> float buffer[(10 * ((int)(44100 * 0.5f)))]*/
    
    /*...*/
    {
        int i;    
        for(i = 0; i < BLOCK_LENGTH; ++i) /*->for(i = 0; i < (10 * ((int)(44100 * 0.5f))); ++i) ::Yeah, defines are cool */
        {
            /*so something with buffer*/
            /*...*/
        }    
    }
    /*...*/
    while(expression)
    {
        if(counter < BUFFER_SIZE) /*-> if(counter < (10 * ((int)(44100 * 0.5f))): Great. Calculation in every cycle...*/
        {
            /*do something*/
        }
    }
    
    //Now C++:
    const unsigned int SAMPLE_RATE = 44100;
    const float BLOCK_LENGTH_S = 0.5f;
    const unsigned int BLOCK_LENGTH = SAMPLE_RATE * BLOCK_LENGTH_S; //evaluates to 22050
    const unsigned int BUFFER_SIZE = 10 * BLOCK_LENGTH; //evaluates to 220500
    
    float buffer[BUFFER_SIZE];
    
    /*...*/
    for(int i = 0; i < BUFFER_SIZE; ++i) //BUFFER_SIZE is 220500 no further calculations are necessary...
    {
    }
    

    Irgendwie finde ich defines doof... 🤡



  • Tachyon schrieb:

    //Now C++:
    

    diese zeile war ja mal sowas von überflüssig 😉



  • #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?


Anmelden zum Antworten