Static functions
Bo Thorsen
bo at sonofthor.dk
Mon Jan 12 13:56:45 GMT 2004
Hi all,
I just convinced myself it was time to remind everyone of this old
feature: Static functions. I know lots of you already know about this
feature, but I've seen too many places where it isn't used, so I thought
I'd give a heads up on it.
The reason for using these is optimization - especially when it comes to
libraries. And since almost all of KDE is made up of libraries, this
really is important.
First application: Helper methods:
There are too many places in KDE where we have helper functions like this:
bool doSomething(...) {
...
}
If you search the object file or the library after compilation (for
example with readelf -s thefile.o) you will see the symbol in the symbol
table of the file. And the places that use these file will have a
reference to this symbol. This means when the runtime linker loads the
library, it needs to spend time matching the call to doSomething with the
place of the code. If you instead do this:
static bool doSomething(...) {
...
}
the symbol is no longer in the object file, and all uses are linked at
compile time, so you no longer spend time in the linker.
Another good thing here is that you won't pollute the local namespace
inside the library, but that point is moot in KDE, since --enable-final
makes it impossible to have two identical methods anyway.
Another application of this: Private methods.
In KMail:kmgroupware.* I had a static attribute called
mKOrganizerIfaceStub. This was used by various internal methods to call
KOrganizer, and there was a connectToKOrganizer method that set up the
stub, and a DCOP slot that listened to the user shutting down KOrganizer.
That means I had this:
class KMGroupware : public QObject {
private slots:
void unregisteredFromDCOP( const QCString& );
private:
void iCalRequest( const QString& receiver, const QString& iCal,
const QString& choice );
void iCalCancel( const QString& iCal );
void iCalReply( const QString& iCal );
static bool connectToKOrganizer();
static KOrganizerIface_stub* mKOrganizerIfaceStub;
};
(all irrelevant parts not shown.) In kmgroupware.cpp I then had the
implementation of all these class items. This is - arguably - a nice
object oriented approach, since the helper functions are private methods
here. It's unfortunately also bad for the runtime linker, since all these
symbols must be relocated at runtime.
The iCal* methods only used the stub, but they were still object methods
because of leftover code from kroupware_branch (all this is from a
refactoring process I did today).
I changed the interface to be this:
class KMGroupware : public QObject {
private slots:
void unregisteredFromDCOP( const QCString& );
};
and in the .cpp file I now have:
static KOrganizerIface_stub* mKOrganizerIfaceStub;
static bool connectToKOrganizer() {
...
}
and so on.
This means the code is basically unchanged, but the header file is less
cluttered and the number of relocations goes down, giving a shorter load
time of the library/application/part.
This is not in any way an advanced feature, and it doesn't make that big a
difference. It's just that there are absolutely no reasons *not* to use
this.
I hope this was interesting or helpful.
Bo.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: signature
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20040112/8ffd610c/attachment.sig>
More information about the kde-core-devel
mailing list