Präprozessor



  • Hallo 🙂

    Danke für deine Antwort. In welcher Reihenfolge der Präprozessor die Quelldateien verarbeitet, hatte ich auch schon überlegt. Damit sind gleich zwei Fragen beantwortet. 🙂

    Dann werde ich mal meine Makros durch inline-Funktionen ersetzen :D.



  • Lass das inline weg, ist sowieso nur eine Empfehlung an den Compiler, der kann eine inline-Funktion draus machen, muss er aber nicht.
    Der Compiler braucht von dir als Entwickler keine Empfehlungen für Optimierungen, er weiß sowieso alles besser, ähnlich wie bei register Variablen.



  • Achso, dann lass ich inline weg.

    Mir wird erst jetzt richtig klar, wie komplex Compiler doch eig. sind. 😃



  • Makro schrieb:

    Achso, dann lass ich inline weg.

    Dann aber auch in einer Sourcedatei definieren!


  • Mod

    Nathan schrieb:

    Makro schrieb:

    Achso, dann lass ich inline weg.

    Dann aber auch in einer Sourcedatei definieren!

    Und dann sind wir wieder bei dem Punkt, an dem es wahrscheinlich nicht mehr optimiert wird. Also doch wieder inline im Header für Minifunktionen.



  • SeppJ schrieb:

    Und dann sind wir wieder bei dem Punkt, an dem es wahrscheinlich nicht mehr optimiert wird. Also doch wieder inline im Header für Minifunktionen.

    Vielleicht können Compiler und Linker auch whole program optimization. Dann muss man sich darüber auch keine Sorgen mehr machen.
    MSVC kann es.
    GCC kann es.



  • So, ich bis nochmal 😃

    Ich hab weiterprobiert und recherchiert und mir ist noch folgendes Problem zu der Verwendung von Konstanten ein. Wenn ich diese im Header als static const NAME = wert; definiere, dann ist static der storage class specifier (Übersetzung - C-Speicherklasse ?) und const der type qualifier (Übersetzung - Typmodifizierer ?).

    Binde ich jetzt den Header (mit z.B. 100 solcher Konstanten ein), werden doch theoretisch alle Konstanten in das entsprechende Programmsegment gelegt. Laut diesem Beitrag:

    How they are stored is an implementation detail (depends on the compiler).

    For example, in the GCC compiler, on most machines, read-only variables, constants, and jump tables are placed in the text section.

    http://stackoverflow.com/questions/1576489/where-are-constant-variables-stored-in-c ist nicht genau definiert, wo diese gespeichert werden.

    Jetzt zu meiner eigentlichen Frage: Ist das speichertechnisch nicht eine Verschwendung so viele Konstanten (z.B. 100) zu speichern und ich verwende im Code dann z.B. nur 3 davon? Oder wird das seitens des Compilers optimiert? Oder habe ich da einen generellen Denkfehler drin? 😃

    Jetzt noch zur inline expansion:

    Bei dieser ist es wichtig, dass der Compiler zur Compiltime die Funktionsdefinition der Funktion vorliegen hat (ist ja i-wie logisch, ansonsten kann der Compiler ja nicht entscheiden, ob die Funkion ersetzt oder aufgerufen wird). Das erreiche ich, indem ich die Funktion direkt in der entsprechenden Datei definiere. Dann muss ich kein inline hinzufügen, oder? Wenn ich die inline Funktion im Header definiere, ist das inline Pflicht?


  • Mod

    Makro schrieb:

    Jetzt zu meiner eigentlichen Frage: Ist das speichertechnisch nicht eine Verschwendung so viele Konstanten (z.B. 100) zu speichern und ich verwende im Code dann z.B. nur 3 davon? Oder wird das seitens des Compilers optimiert? Oder habe ich da einen generellen Denkfehler drin? 😃

    Die Antwort, dass das ein Implementierungsdetails ist, ist schon richtig, wenn auch nicht nützlich. In vielen Fällen wird die Konstante aber wohl überhaupt keine Repräsentation mehr im Speicher haben, sondern direkt im Programmcode eingesetzt werden. Das ist ja gerade der Sinn der Sache.

    Bei dieser ist es wichtig, dass der Compiler zur Compiltime die Funktionsdefinition der Funktion vorliegen hat (ist ja i-wie logisch, ansonsten kann der Compiler ja nicht entscheiden, ob die Funkion ersetzt oder aufgerufen wird). Das erreiche ich, indem ich die Funktion direkt in der entsprechenden Datei definiere. Dann muss ich kein inline hinzufügen, oder? Wenn ich die inline Funktion im Header definiere, ist das inline Pflicht?

    Und wie willst du Funktionen im Header ohne inline definieren? Als static? Der Header kann schließlich von mehreren Übersetzungseinheiten eingebunden werden und du darfst nur eine Definition einer Funktion im Gesamtprogramm haben. Ausnahmen sind eben static-Funktionen (dann hast du in jeder Übersetzungseinheit eine separate Funktion, von der die anderen Einheiten nichts mit bekommen. Die Funktionen dürfen sich sogar unterscheiden) oder inline. Dies ist der Hauptzweck von inline.



  • Hi 🙂

    Die Antwort, dass das ein Implementierungsdetails ist, ist schon richtig, wenn auch nicht nützlich. In vielen Fällen wird die Konstante aber wohl überhaupt keine Repräsentation mehr im Speicher haben, sondern direkt im Programmcode eingesetzt werden. Das ist ja gerade der Sinn der Sache.

    Hmm, wenn der Header eingebunden wird, sind die static const Variablen doch aber erstmal normale Variablen oder? Die Konstanten, die ich verwende, können ja direkt ersetzt werden, aber was passiert mit den Konstanten, die ich ja als "normale" Variablen deklariere und initialisiere und nicht verwende? (Falls ich zu unverständlich schreibe, bitte sagen :))


  • Mod

    Die Konstanten, die ich verwende, können ja direkt ersetzt werden, aber was passiert mit den Konstanten, die ich ja als "normale" Variablen deklariere und initialisiere und nicht verwende?

    Da die Konstante static ist, weiß der Compiler ja, dass sie nirgends außerhalb der Übersetzungseinheit benutzt wird und braucht daher auch keinen Speicherplatz für die Konstante zu erzeugen, außer es ist aus irgendeinem Grund für die aktuelle Übersetzungseinheit nötig (etwa weil du die Adresse der Konstante benutzt). Das ist natürlich keine Garantie, dass er das nicht trotzdem tut, Implementierungsdetail eben. Aber es wäre komisch, denn der Grund, wieso es solche Konstanten gibt, ist, dass man dann eben diese Art von Optimierung durchführen kann.

    Hmm, wenn der Header eingebunden wird, sind die static const Variablen doch aber erstmal normale Variablen oder?

    Wir reden hier schon von C99, oder? Ich bin den ganzen Thread über davon ausgegangen, da erst ab C99 const-Variablen überhaupt richtige Compilezeitkonstanten sind. Wenn wir von C89 reden, dann kannst du den gesamten Thread vergessen.



  • Da die Konstante static ist, weiß der Compiler ja, dass sie nirgends außerhalb der Übersetzungseinheit benutzt wird und braucht daher auch keinen Speicherplatz für die Konstante zu erzeugen, außer es ist aus irgendeinem Grund für die aktuelle Übersetzungseinheit nötig (etwa weil du die Adresse der Konstante benutzt). Das ist natürlich keine Garantie, dass er das nicht trotzdem tut, Implementierungsdetail eben. Aber es wäre komisch, denn der Grund, wieso es solche Konstanten gibt, ist, dass man dann eben diese Art von Optimierung durchführen kann.

    Alles klar, damit ist meine Frage beantwortet, danke dir :).

    Wir reden hier schon von C99, oder? Ich bin den ganzen Thread über davon ausgegangen, da erst ab C99 const-Variablen überhaupt richtige Compilezeitkonstanten sind. Wenn wir von C89 reden, dann kannst du den gesamten Thread vergessen.

    Jo, wir reden hier von C99.



  • Ich bin immer wieder fasziniert was die Leute hier so an Wissen mitbringen 🙂
    @SeppJ , @hustbear und so:)

    Respekt:) 👍 👍



  • SeppJ schrieb:

    da erst ab C99 const-Variablen überhaupt richtige Compilezeitkonstanten sind.

    ? Zeig mal, wo das steht.
    const bleibt const in C, egal ob C89 oder C99, Compilezeitkonstanten sind sie (im Gegensatz zu C++) beide Male nicht.
    Die einzigen Unterschiede, die mir zw. C89 und C99 gerade einfallen sind VLA-Dimensionen und Initialisierer bei static Objekten.

    const int i = 10;
    int a[i];
    /* funktioniert nur in C99, heißt aber noch lange nicht, dass i eine Konstante zur Compilezeit ist. */
    
    const double pi = 4 * atan(1);
    /* ist konform in C89 und C99, weil pi eben keine Compilezeit-Konstante ist, da sie erst zur Laufzeit initialisiert wird/werden kann,
    und erst danach dann (also zur Laufzeit) unveränderlich/konstant ist. */
    

  • Mod

    Wutz schrieb:

    SeppJ schrieb:

    da erst ab C99 const-Variablen überhaupt richtige Compilezeitkonstanten sind.

    ? Zeig mal, wo das steht.
    const bleibt const in C, egal ob C89 oder C99, Compilezeitkonstanten sind sie (im Gegensatz zu C++) beide Male nicht.
    Die einzigen Unterschiede, die mir zw. C89 und C99 gerade einfallen sind VLA-Dimensionen und Initialisierer bei static Objekten.

    Tatsächlich. Da bin ich wohl selber gewolft worden. Man sieht meine Aussage sehr oft in verschiedenen Quellen, die aber offenbar wohl alle eher mit Vorsicht zu genießen sind. Aber im Standard ist es tatsächlich nicht erlaubt und meine soeben gemachten Tests (ich habe das vorher nie wirklich geprüft) schlagen auch tatsächlich fehl.



  • Bedeutet das jetzt, dass diese Art der Optimierung:

    Da die Konstante static ist, weiß der Compiler ja, dass sie nirgends außerhalb der Übersetzungseinheit benutzt wird und braucht daher auch keinen Speicherplatz für die Konstante zu erzeugen, außer es ist aus irgendeinem Grund für die aktuelle Übersetzungseinheit nötig (etwa weil du die Adresse der Konstante benutzt). Das ist natürlich keine Garantie, dass er das nicht trotzdem tut, Implementierungsdetail eben. Aber es wäre komisch, denn der Grund, wieso es solche Konstanten gibt, ist, dass man dann eben diese Art von Optimierung durchführen kann.

    nicht durchgeführt wird? Oder hat das erstmal primär mit static zu tun (hab das in deinem Text nicht ganz rauslesen können, ob du hier als Konstante eine Variable meinst, die auf jeden Fall "const" als Qualifier haben muss) und nicht mit const, für das ich als Definition immer nur read-only gefunden habe (http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html), was nicht heißt, dass man das nicht umgehen kann.


  • Mod

    Doch, diese Optimierung kann immer noch durchgeführt werden. Und ja, das static spielt dabei eine wichtige Rolle. Es würde sogar ohne das const gehen, denn der Compiler kann schließlich sehen, dass die Variable nirgendwo verändert wird.



  • Danke @SeppJ und auch nochmal danke @Wutz 🙂


Anmelden zum Antworten