------- Comment #13 from herwig at gdsys dot de 2008-04-02 16:07 ------- (In reply to comment #12) > The point I meant to make but failed is: a pure virtual method can *only* > *ever* be called explicitly. It can't be called through the vtable because > there can be no objects of the type of this pure class, only of derived > classes, and in the vtables of this derived class the slot for this > virtual function is filled by another function (because the derived class, > to be instantiated, must have overwritten the pure function).
You are absolutely right as long as there is no multithreading and no dangling pointer. Sure. The thing is: If it's called, something bad has occured and I want to catch it let's say for a backtrace at this point. Or I take it deliberately into account and let it perform a no-op. When searching for an example, I came across this link: http://www.artima.com/forums/flat.jsp?forum=226&thread=196881#270009 This post is the exact description of the problem I initially ran into. Even to proposed solution is part of what I've done to prevent the call. > So, yes, I'm not surprised that the object file you produce from your > testcase doesn't contain pvMethod. But that's not a problem because in it > nobody ever calls this function. What I want to see is a testcase in which > this function *should* be there because it is, somehow, called or > otherwise required. Okay, here it is, the faulty code: ;) #include <iostream> #include <pthread.h> using namespace std; template<class T> class TBase { public: ~TBase(); virtual void pvMethod() = 0; }; template<class T> TBase<T>::~TBase() { sleep(2); } template<class T> void TBase<T>::pvMethod() { cerr << "Error" << endl; } class TDerived : public TBase<TDerived> { public: void pvMethod(); }; void TDerived::pvMethod() { cout << "OK" << endl; } int startThread(pthread_t* handle, void* (*entry)(void*), void* arg) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, true); int res = pthread_create(handle, &attr, entry, arg); pthread_attr_destroy(&attr); return res; } void* thread(void* arg) { TDerived** typed_arg = (TDerived**)arg; TDerived* obj = *typed_arg; sleep(1); delete obj; *typed_arg = 0; return 0; } int main(int argc, char** argv) { TDerived* obj = new TDerived; pthread_t thread_handle; startThread(&thread_handle, &thread, &obj); for (int i = 0; i < 5; ++i) { if (!obj) { break; } obj->pvMethod(); sleep(1); } return 0; } [EMAIL PROTECTED]:~/Programming$ g++ -O0 -Wall -lpthread test.cpp -o test && ./test OK OK pure virtual method called terminate called without an active exception Abgebrochen > Does this make sense? The standard says "A pure virtual function need be defined only if explicitly called with the qualified-id syntax (5.1)." in 10.4.2, so it's perfectly legal to omit the pvMethod(). But there is a discrepancy between templates and normal classes: * For normal classes the method is generated, even if not used. GCC developers decided to do more than the standard requires, and they must have reasons to do so. Here you have a choice. * For templates the method is not generated, and we've discussed why. It's due to the template function emission rules: Not called, not emitted. But there is also the shortcut rule when deriving: Cannot be called, not emitted. That is what you explained. Thus here you have no choice. Honestly, wouldn't you also like to have the choice? Best, Björn! -------------------------------------------------------------------------- Dipl.-Ing. Björn A. Herwig Guntermann & Drunck GmbH Systementwicklung Dortmunder Str. 4a D-57234 Wilnsdorf - Germany Tel: +49 (0) 27 39 / 89 01 - 100 Fax: +49 (0) 27 39 / 89 01 - 120 E-Mail: mailto:[EMAIL PROTECTED] Web: www.gdsys.de -------------------------------------------------------------------------- Geschäftsführer: Udo Guntermann - Martin Drunck - Reiner Ruelmann - Klaus Tocke HRB 2884, Amtsgericht Siegen USt.-Id.-Nr. DE 126575222 - Steuer-Nr. 342 / 5835 / 1041 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33878