[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-devel
Subject: Re: C++ exceptions
From: Lubos Lunak <l.lunak () suse ! cz>
Date: 2005-12-08 0:24:38
Message-ID: 200512080124.39396.l.lunak () suse ! cz
[Download RAW message or body]
Dne středa 07 prosinec 2005 22:40 Volker Lukas napsal(a):> Thiago Macieira wrote:> > Volker \
Lukas wrote:> >>> Hmm... I think you misunderstood again:> >>> >>I do not have that impression. \
To be clear, I am talking about> >> situations like the following:> >>-----------> >>class \
my_widget : public QWidget> >>{> >>virtual void paintEvent(QPaintEvent*)> >> { ... throw \
something(); ... }> >>};> >>----------> >> > Ok, then we are talking about the same thing.> >> \
> That's the exact kind of code that I'm telling you you can expect to> > crash.>> As I have \
> written in my first message: Trolltech does intend this code to> work correctly, i.e. \
> whenever a problem is reported arising from such> situations, this is classified by them as a \
> bug and will probably get> fixed. And it is not documented that this would not be allowed, at \
> least> considering the reference documentation, which would be an appropriate> place.>> So \
> no, I do not expect that this will crash, because I both know from> Trolltech-sources that it \
> should not, and from my own observations that it> does not.
Hmm. Care to provide some more details on the latest paragraph, e.g. some links? It's just \
that my observations think otherwise (Qt3): (gdb) bt#0 my_widget::paintEvent \
(this=0xbfe3cc90, e=0xbfe3c6e0) at a.cpp:13#1 0x40848cd2 in QWidget::event (this=0xbfe3cc90, \
e=0xbfe3c6e0) at qwidget.cpp:4809#2 0x407a25c0 in QApplication::internalNotify \
(this=0xbfe3cbc4, receiver=0xbfe3cc90, e=0xbfe3c6e0) at qapplication.cpp:2635#3 0x407a312f in \
QApplication::notify (this=0xbfe3cbc4, receiver=0xbfe3cc90, e=0xbfe3c6e0) at \
qapplication.cpp:2523#4 0x400cd39e in KApplication::notify (this=0xbfe3cbc4, \
receiver=0xbfe3cc90, event=0xbfe3c6e0) at \
/home/seli/build/_k3/src/kdelibs/kdecore/kapplication.cpp:550#5 0x407337e3 in \
QApplication::sendSpontaneousEvent (receiver=0xbfe3cc90, event=0xbfe3c6e0) at \
qapplication.h:499#6 0x407288ac in QETWidget::translatePaintEvent (this=0xbfe3cc90, \
event=0xbfe3c9f8) at qapplication_x11.cpp:5647#7 0x4072dfcf in QApplication::x11ProcessEvent \
(this=0xbfe3cbc4, event=0xbfe3c9f8) at qapplication_x11.cpp:3496#8 0x4074655c in \
QEventLoop::processEvents (this=0x80b0410, flags=4) at qeventloop_x11.cpp:192#9 0x407bad2e in \
QEventLoop::enterLoop (this=0x80b0410) at qeventloop.cpp:198#10 0x407bac57 in QEventLoop::exec \
(this=0x80b0410) at qeventloop.cpp:145#11 0x407a1149 in QApplication::exec (this=0xbfe3cbc4) at \
qapplication.cpp:2758#12 0x0804ba70 in main (argc=1, argv=0xbfe3cd84) at a.cpp:27 First of \
all, this clearly shows that in this specific case the exception can be caught only in main(). \
So the exception has to propagate through all the functions above. QWidget::event() - \
ok.QApplication::internalNotify() - the "e->spont = FALSE;" at the end won't be executed, but \
who cares about that in main().QApplication::notify() - ok.KApplication::notify() - let's \
ignore this and say it's Qt-only. QApplication::sendSpontaneousEvent() - \
okQETWidget::translatePaintEvent() - calls to qt_clear_paintevent_clipping() and clearWState( \
WState_InPaintEvent ) are avoidedQApplication::x11ProcessEvent() - \
okQEventLoop::processEvents() - there's actually a lot skipped, but that seems to be \
harmlessQEventLoop::enterLoop() - a lot of eventloop state manipulation is \
restoredQEventLoop::exec() - the sameQApplication::exec() - ok There are at least three cases \
which potentionally can lead to malfunction. You it's a bad example because it causes leaving \
the event loop? Let's try another one. class X : public QObject { Q_OBJECT public: \
void s() { emit sig(); } public slots: void sl(); signals: void sig(); \
};int main( int argc, char* argv[] ) { X x; QObject::connect( &x, SIGNAL( sig()), &x, \
SLOT( sl())); x.s(); } (gdb) bt#0 X::sl (this=0xbfe0383c) at a.cpp:23#1 0x080496be in \
X::qt_invoke (this=0xbfe0383c, _id=2, _o=0xbfe0379c) at a.moc:90#2 0x40367d9b in \
QObject::activate_signal (this=0xbfe0383c, clist=0x804e0b0, o=0xbfe0379c) at qobject.cpp:2356#3 \
0x4036887f in QObject::activate_signal (this=0xbfe0383c, signal=2) at qobject.cpp:2325#4 \
0x080495f2 in X::sig (this=0xbfe0383c) at a.moc:84#5 0x0804992f in X::s (this=0xbfe0383c) at \
a.cpp:12#6 0x0804964a in main (argc=1, argv=0xbfe038e4) at a.cpp:29 X::qt_invoke() - \
okQObject::activate_signal( QConnectionList*, QUObject* ) - restoring of the value for \
QObject::sender() is skipped and there's a potential leak. Since it's rather obvious here that \
even signals/slots handling is not exception-safe in Qt I guess I can stop now. So, how should \
I put it ... ah yes: I think you're wrong. If even such basic thing like signals/slots \
handling is not ok, and if there's one place in Qt you'd need handled correctly then it's this \
place, then no way it can work in places like paintEvent() or anywhere else. And even if you \
report this specific case to Qt (which I guess should be done), that's still not enough for \
whole Qt. Qt is not written with exceptions in mind at all and cleaning this up would probably \
require quite some effort. Qt4 seems to have signals/slots handling exceptions-safe, but my \
guess would be it's about the only such place (I can't check now, but e.g. the event loop case \
is again not safe). Since this is kde-devel@, we're talking KDE3 now anyway. End of story. As \
for the actual performance impact of using exceptions, the original reason for -fno-exceptions \
is not true anymore, it seems exceptions with current gcc versions don't cause any additional \
per-process memory usage and all the data is shared. Moreover it's put together in the binary \
and it seems it's not touched at all during normal execution (assuming the calls to \
_Unwind_Resume don't touch it, which I'd say they don't), so theoretically it doesn't even need \
to be loaded from the disk. "Theoretically" because it's right between the needed readonly and \
non-readonly parts, and moreover e.g. SUSE has a patch which tries to (pre)load the whole \
binary linearly in order to increase performance. Numbers about runtime and size overhead could \
be either found somewhere on the net or benchmarked (Thiago's claim about glib size is rather \
vague without him stating which versions he means :) ) and then there's also the question how \
it'd compare to all those manual error checks removed. Who knows, I don't *shrug*. That said, \
I personally think that if somebody wants to use exceptions in their own code _only_, just go \
for it.
-- Lubos LunakKDE developer---------------------------------------------------------------------SuSE \
CR, s.r.o. e-mail: l.lunak@suse.cz , l.lunak@kde.orgDrahobejlova 27 tel: +420 2 9654 2373190 \
00 Praha 9 fax: +420 2 9654 2374Czech Republic http://www.suse.cz/ >> Visit \
http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic