------- 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

Reply via email to