Hi Lubos, > QCString has a virtual method, its destructor (people, why are you so lazy > to repeat the 'virtual' keyword in derived classes? Writing the QArray > destructor as 'virtual ~QArray(){}' makes things easier to read, and it's Don't ask me ... ;) > only few more keypresses). But ~QCString() is not implemented anywhere, > it will be generated automatically by the compiler. The situation is similar > with QArray, where the destructor is implemented, but it's inline (methods > implemented in the class body are treated as inline), so there's again no > .cpp file implementing it. Here gcc could be smarted and realize it can > generate the vtable in the module implementing the first non-virtual method > of the class, but it doesn't do so (feel free to send mails to your > favourite g++ developer asking when it will do so). Here again the hack > with private put_vtable_only_here() can help, the other choice is to > really implement the destructor as non-inline. Has been done for the upcoming Beta 6. Any other striking places ? I just hope that the tradeoffs memory vs. speed are always justified. > If you look in qvaluelist.h, you'll notice that all template classes > in this header file have their methods implemented in the class body, which > automatically makes them inline, even if they aren't explicitly marked so. > Some of the methods are quite large and this causes larger executables. > Moreover gcc won't inline some of them (compile with -Winline to see), I'll take a look. > because they are simply too large or for other reasons. Instead inlining > them, an out-of-line copy for them will be created, and such multiple > copies will cause conflicts. All large methods in templates should be moved > out of the class body, so they won't be treated as inline. Also, they > should be either enclosed by an #ifdef block, or they should be > in a separate source file. Since the definitions of non-inline template > methods won't be available, they won't be instantiated anywhere. I'm not sure I understand. Is the separation mandatory to convince the compiler ? Will it always instantiate all non-inline methods otherwise ? Or would an #ifdef simple help the developer by producing a compile error unless he points the compiler to an already existing instance ? > That should answer how to prevent other places from creating duplicate > copies. The question where and how the one single instance of template > should be created still remains. An instance can be created by putting > 'template QValueList< QString >;' in one source file, after #including > a file with complete definition of QValueList< T >, including non-inline > methods. With older C++ compilers that can't handle this construct, one > uses 'typedef QValueList< QString > QValueListQString;' instead. The place Didn't know that typedef should have such an effect. > where one specific template instance should be created is of course > the library where it's first used, in this QValueList< QString > case, > it's libqt. > > There are still two problems remaining. One of them is the fact that > QValueList< QString > may one day disappear from a newer Qt version > (e.g. because QMap< QString > is used instead it). This would break > binary compatibility for KDE libraries relying on QValueList< QString > > being present in libqt - after upgrading to this newer Qt version, Such an export would of course have to be treated like a part of the binary interface and there remain unchanged between minor revisions. Considering the missing experience with such techniques, I can only imagine it to be an experimental (#ifdef'ed) feature for the start. Where do you see the bigger potential for savings ? On the source design or compiler's side ? It seems like quite a few things could be done in gcc without affecting the coder at all (e.g. your .almostrodata suggestion). Thanks for you analysis work, Harri.