[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