Help a mate: an extremely strange bug on GCC/ld ?

koos vriezen koos.vriezen at gmail.com
Sat Dec 6 16:44:41 GMT 2008


2008/12/6 Olivier Goffart <ogoffart at kde.org>:
> Le samedi 6 décembre 2008, koos vriezen a écrit :
>> 2008/12/6 Olivier Goffart <ogoffart at kde.org>:
>> > Reimplementing an existing virtual method is fine if you can accept that
>> > it is not called if the program reimplementing the class is not
>> > re-compiled (i.e, if the feaure added in that implementation is
>> > optional.)
>>
>> Huh, isn't that true for every source code that isn't compiled, ie.
>> please explain.
>>
>> Koos
>
> For this explanation, i assume you know what a virtual table is
> (http://en.wikipedia.org/wiki/Virtual_table)
>
> Let's suppose you have the class DolphinListView, which inherit from
> KCategorizedView which itself inherit from QListView
>
> In KDE 4.1, KCategorizedView doesn't reimplement the virtual function
> rowsAboutToBeRemoved.  So DolphinListView's virtual table points to
> QListView::rowsAboutToBeRemoved
>
> Now, in KDE 4.2,  KCategorizedView::rowsAboutToBeRemoved is reimplemented,
> but if dolphin is not compiled, DolphinListView's virtual table doesn't
> change and still points to QListView::rowsAboutToBeRemoved
>
> That means that KCategorizedView::rowsAboutToBeRemoved will not be called for
> any call to this function.
> That's ok if the code in the new KCategorizedView::rowsAboutToBeRemoved is
> just a bugfix or a new feature optional feature.  But this is not ok if some
> other code in other function of KCategorizedView relies on the fact that
> KCategorizedView::rowsAboutToBeRemoved should have been called.
>
> I hope this answer the question.

Yes thanks for this insight.

For reference, this is the experiment I did to verify (and Olivier is right)

shared.h:
class A {
    public:
        virtual char foo() const;
        virtual char bar() const;
};

class B : public A {
#ifdef B_HAS_FOO
    public:
        virtual char foo() const;
#endif
};

shared.cpp:
#include "shared.h"

char A::foo() const { return 'A'; }
char A::bar() const { return 'X'; }
#ifdef B_HAS_FOO
char B::foo() const { return 'B'; }
#endif

application.cpp:
#include <stdio.h>
#include "shared.h"

class C : public B {
    public:
        virtual char bar() const { return 'Z'; }
};

int main() {
    A *a = new C;
    printf( "call of foo: %c\n", a->foo() );
    return 0;
}

g++ -shared -fPIC shared.cpp -o libshared.so
g++ application.cpp -o application -L. -lshared
LD_LIBRARY_PATH=. ./application
call of foo: A
g++ -shared -fPIC shared.cpp -o libshared.so -DB_HAS_FOO
call of foo: A
g++ application.cpp -o application -L. -lshared -DB_HAS_FOO
call of foo: B


Thanks,
Koos


More information about the kde-core-devel mailing list