[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: Reducing the number of conflicts in libraries
From:       Lubos Lunak <l.lunak () sh ! cvut ! cz>
Date:       2001-09-21 18:31:03
[Download RAW message or body]

Dne pá 21. záøí 2001 18:54 Harri Porten napsal(a):
> 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.

 Hmm, I don't see any such changes in today's rsync. As for the memory vs. 
speed, if you use the put_vtable_only_here() hack, that's just one more 
vtable entry and no speed loss. Other possibility would be to use the #pragma 
interface/implemention GCC extension, but I don't like that one (it breaks 
with --enable-final, it is as much work as simply changing the classes, and 
so on).

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

 Non-inline template methods should be only instantiated when needed, but 
this still can lead to duplicates. Separating the non-inline methods from the 
template class definition would usually result in link errors, forcing the 
developer to use explicit instantiation. So there would have to be some 
#ifdef controlling whether to separate or not.

>
> >  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.

 Only in old compilers that don't know 'template QValueList< QString >;'. At 
least I seem to remeber I used to do it with BC++3.1 .

>
> > 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.

 Of course.

>
> 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).

 Well, I actually think it could be completely handled by gcc/ld/prelink, so 
when one nice day this becomes true, doing all this would only help to 
slightly reduce to size of libs/binaries, and maybe help on non-GNU platforms 
(I have no idea what the situation e.g. on *BSD is). The point is that this 
'one nice day' will probably come later than a widely usable version of 
prelink. Distros may start to ship prelink as experimental feature in few 
months, still with gcc that won't support this almost complete elimination of 
conflicts.
 I was just asking if people think it would be worth it. I think I'll try to 
compile qt and part of kdelibs with -fno-implicit-templates and only explicit 
instantiation, so I can tell how this affects libraries sizes. Adding this 
explicit template instantiation to Qt can wait. Maybe it won't be worth the 
trouble at all, or it could be used only in some rather simple cases.


 Lubos Lunak
-- 
 llunak@suse.cz ; l.lunak@kde.org
 http://dforce.sh.cvut.cz/~seli

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic