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