inline Fertigkeiten des compilers



  • ich frage mich manchmal, wie gut der Compiler eine Funktion inline macht. Als Beispiel mal:

    typedef struct __list {
        struct __list* next;
        struct __list* prev;
    } list;
    void list_remove(list* entry) {
        entry->prev->next = entry->next;
        entry->next->prev = entry->prev;
    }
    
    void list_add(list* here, list* entry) {
        entry->next = here->next;
        entry->prev = here;
    
        here->next->prev = entry;
        here->next = entry;
    }
    
    void list_replace(list* eold, list* enew) {
        enew->next = eold->next;
        enew->prev = eold->prev;
    
        enew->next->prev = enew;
        enew->prev->next = enew;
    
        eold->next = eold;
        eold->prev = eold;
    }
    

    theoretisch könnten wir jetzt den code in list_replace ersetzten durch:

    void list_replace(list* eold, list* enew) {
        list_add(eold,enew);
        list_remove(eold);
    }
    

    Das wäre übersichtlicher
    Hätte aber einen Funktionsoverhead
    Checkt der Compiler (z.B. gnu) das und macht das inline?
    Oder sollte ich die inline Direktive verwenden?



  • Du kannst es einfach lokal mit der gcc-Option -S oder online mit dem C++ Compiler Explorer überprüfen (den entsprechenden C++ Compiler auswählen und schauen welcher Assemblercode dafür generiert wird - du kannst auch weitere Compileroptionen z.B. -O2 dort angeben).

    Das Schlüsselwort inline sollte man nicht mehr zur Angabe der Optimierung verwenden, da es eine andere Bedeutung bekommen hat, s. inline specifier (unter "Explanation" ab "The original intent of the inline keyword...") - der deutsche Artikel zu inline hat leider noch die ursprüngliche Bedeutung beschrieben.


  • Mod

    @Th69 sagte in inline Fertigkeiten des compilers:

    Das Schlüsselwort inline sollte man nicht mehr zur Angabe der Optimierung verwenden, da es eine andere Bedeutung bekommen hat, s. inline specifier (unter "Explanation" ab "The original intent of the inline keyword...") - der deutsche Artikel zu inline hat leider noch die ursprüngliche Bedeutung beschrieben.

    Auch wenn's ursprünglich im C++-Bereich gestellt wurde, ist wohl doch reines C gemeint vom Code her. Nicht das inline in C zwingend das bedeuten würde, dass die Funktion geinlined wird, aber das Verhalten bezüglich der Linkage hat subtile Unterschiede im Vergleich zu C++. Siehe die Erklärung für C in derselben Referenz: https://en.cppreference.com/w/c/language/inline

    Tendenziell vertragen sich inlining und Pointer nicht so gut, besonders in C. Wenn du Th69s Rat folgst und ein bisschen herumspielst, wirst du sehen, dass ein optimierender Compiler zwar die Funktionen inlinen würde, aber der Code doch anders ausschaut, als wenn du die Funktionen selber inline schreibst. Das liegt an der Möglichkeit von Pointer Aliasing. Der Compiler muss hier annehmen, dass die Zeiger potentiell aufeinander zeigen könnten, und wenn man darüber Werte verändert, wird auf einmal die Reihenfolge der Operationen wichtig, und Optimierungen werden dadurch erschwert. Schau mal, was das restrict-Schlüsselwort macht (nur C, nicht C++, da in c++ nicht nötig). Die am besten optimierbarste Variante deines Codes sollte in diese Richtung gehen:

    void list_replace(list* restrict eold, list* restrict enew) {
        list_add(eold,enew);
        list_remove(eold);
    }
    

    Vorausgesetzt, du kannst garantieren, dass hier kein Aliasing stattfindet. Wenn doch, dann passieren unerwartete Dinge.



  • @SeppJ sagte in inline Fertigkeiten des compilers:

    Schau mal, was das restrict-Schlüsselwort macht (nur C, nicht C++, da in c++ nicht nötig).

    Wieso sollte restrict in C++ nicht nötig sein? Da gibt's genau das selbe Problem, also dass der Compiler oft Optimierungen nicht machen kann, weil er nicht wissen kann ob Zeiger bzw. Referenzen vielleicht auf das selbe Objekt zeigen.


  • Mod

    @hustbaer sagte in inline Fertigkeiten des compilers:

    Wieso sollte restrict in C++ nicht nötig sein?

    Weil ich die Aliasing-Regeln nicht mehr richtig im Kopf habe 🙂

    Aber in C++ gibt's restrict halt nicht (außer als compilerspezifische Erweiterung).


Anmelden zum Antworten