[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