template instantiation



  • zuerst würde ich gern wissen, ob folgende implementierung bzw. vorgehensweise auch für euch als optimal anzusehen ist:
    - für ein projekt wird für jede template instantiation der code einmal erzeugt.
    - liegt der code einer template instantiation in einer bibliothek schon vor, muss er zumindest nicht in das ergebnis des pakets (lib oder exe) eingelinkt werden. das compilieren wird man kaum verhindern können.

    derzeit kommt man nur manuell und teilweise gar nicht zu diesem ergebnis.
    den ersten punkt könnte man erreichen, indem man eine code datei erzeugt, die alle source dateien inkludiert. das hat aber zum einen den nachteil, dass man den compilier-fortschritt nicht erkennen kann. bei großen paketen könnte dann auch der ram ausgehen, wenn man nicht echt sehr viel davon hat.

    den zweiten punkt konnte ich bis jetzt gar nicht erreichen.

    ein weiteres problem mit templates ist, dass man jedes paket, das ein template verwendet, neu compilieren muss, sollte sich das template ändern. (z.b. ein bug behoben wurde.)

    wie macht ihr das?



  • er.
    also ... der code des templates darf AFAIK im fertigen binary auch nur 1x vorliegen, sonst würden ja unterschiedliche programmstellen unterschiedliche adressen rausbekommen wenn sie die adresse z.B. einer template funktion nehmen.

    ansonsten: function-level-linking und link-time-code-generation, damit sollten keine unnötigen duplikate mehr übrigbleiben. schneller beim compilieren wird dadurch natürlich auch nix, sondern sogar langsamer. allerdings hab ich noch kein projekt wo die compile-zeiten mich total umbringen würden. 30min für alle libraries die für irgendein projekt gebraucht werden sind schnell um, aber das ist IMO noch erträglich. vor allem compiliert man die grossen libraries ja auch nicht jeden tag neu.



  • namenlos schrieb:

    - liegt der code einer template instantiation in einer bibliothek schon vor, muss er zumindest nicht in das ergebnis des pakets (lib oder exe) eingelinkt werden. das compilieren wird man kaum verhindern können.

    wenn ich dich richtig verstanden habe, dann willst du die implizierte instanziierung eines templates an einer bestimmte stelle im client code verhindern (weil die instanziierungs des templates bereits an anderer stelle geschehen ist) - richtig?

    das geht mit C++ im moment nicht. allerdings unterstützen sowohl GCC, Metrowerks, Microsoft, Comeau und der Borland-Compiler unterstützen bereits externe templates, die dir die kontrolle über den punkt der instanziierung geben (und unnötige compilezeiten drastisch verkürzen):

    template <class T>
    struct foo { void bar () {} };
    
    extern template class foo<int>;
    
    void bar (foo<int>& f)
    {
       f.bar(); //foo<int> wird hier nicht! instanziiert
    }
    
    template class foo<int>; //erst hier
    

    ein weiteres problem mit templates ist, dass man jedes paket, das ein template verwendet, neu compilieren muss, sollte sich das template ändern. (z.b. ein bug behoben wurde.

    tja.



  • hustbaer schrieb:

    er.
    also ... der code des templates darf AFAIK im fertigen binary auch nur 1x vorliegen, sonst würden ja unterschiedliche programmstellen unterschiedliche adressen rausbekommen wenn sie die adresse z.B. einer template funktion nehmen.

    das seh ich gleich. wenn man aber ein template mit gleichen parametern in zwei verschieden source code dateien verwendet, die nicht gleichzeitig compiliert werden, erzeugt zumindest g++ den code in beiden. der linker wirft dann alle dublikate raus. das sollte ganz umgangen werden.

    hustbaer schrieb:

    ansonsten: function-level-linking und link-time-code-generation, damit sollten keine unnötigen duplikate mehr übrigbleiben.

    ich denke, dass das die option -frepo bei g++ ist und collect2 dann die dateien neu compiliert. ich hab das ausprobiert. das klappt natürlich. ob es so praktisch ist, weiß ich nicht. verwendet das jemand standardmäßig? es löst aber zumindest problem 1. problem 2 bleibt weiter bestehen.



  • queer_boy schrieb:

    wenn ich dich richtig verstanden habe, dann willst du die implizierte instanziierung eines templates an einer bestimmte stelle im client code verhindern (weil die instanziierungs des templates bereits an anderer stelle geschehen ist) - richtig?

    richtig. ein beispiel kann sein, dass die api einer bibliothek aus mehrern klassen besteht. klasse1 hat eine methode, die eine std::list<klasse2> zurückgibt. es sollte damit der code für std::list<klasse1> in der bibliothek liegen und von dort verwendet werden.

    queer_boy schrieb:

    das geht mit C++ im moment nicht. allerdings unterstützen sowohl GCC, Metrowerks, Microsoft, Comeau und der Borland-Compiler unterstützen bereits externe templates, die dir die kontrolle über den punkt der instanziierung geben (und unnötige compilezeiten drastisch verkürzen):

    jep. auch das hab ich gelesen und ausprobiert. klappt ebenso. es hat aber den nachteil, dass es nicht standardkonform ist. grundsätzlich ist das sicher die mächtigste lösung, weil sie am meisten freiheiten lässt und die header datei einer bibliothek genau angeben kann, für welche templates sie code enthält. es stellt sich die frage, ob es schon ausreicht, dass der code in der bibliothek ist, um nur die bibliothek neu compilieren zu müssen, sobald sich der code des templates ändert.



  • lagere so viel code aus, wie möglich - arbeite so wenig generisch wie möglich.
    das ist eben der haken an templates.

    ps. wenn du noch ein, zwei jahre wartest, ist extern template im standard. sehr unwahrscheinlich, dass das noch rausgestrichen wird.



  • @namenlos:
    OK, dann hatte ich dich falsch verstanden.
    Bzw. ich verstehe immer noch nicht GANZ worauf du hinaus willst.
    Geht es dir um die Compile-Zeiten?
    Wenn ja, OK, das verstehe ist.

    Wenn nein, ..., nur dass irgendwas doppelt und dreifach compiliert, gelinkt, und verworfen wird ist mir solange egal solange es a) nicht zulange dauert und b) nicht in der fertigen "exe"/"dll" übrigbleibt.

    b) kann man eben mit diversen Compiler- und Linker-Optionen erreichen, und für a) kenne ich keine gute Lösung.



  • es gibt kein problem, das nicht auch ohne templates gelöst werden kann. wenn dir compilezeiten wichtiger sind als alles andere, verzichte halt auf templates 😉



  • die compilier-zeiten sind eher nur zweitrangig. es geht einerseits darum, die features einer sprache optimal auszunützen. und ein problem damit zu lösen, dass man sich einfach einschränkt, bringt wenig meiner meinung nach.
    andererseits geht es mir auch darum, dass alle pakete zusammen möglich wenig platz verbrauchen, um ressourcenschonend zu sein.


Log in to reply