open-watcom / open-watcom-v2

Open Watcom V2.0 - Source code repository, Wiki, Latest Binary build, Archived builds including all installers for download.
Other
989 stars 162 forks source link

error "function address cannot be converted to pointer to class member" #1245

Open Baron-von-Riedesel opened 8 months ago

Baron-von-Riedesel commented 8 months ago

I get this error when trying to compile DosBox's FM synthesizer with OW. I stripped down the code to a relatively simple test case:

#include <stdio.h>

typedef enum {
    sm2AM,
    sm2FM,
    sm3AM,
    sm3FM,
} SynthMode;

struct channel;

typedef void ( channel::*SynthHandler) ( int );

struct channel {
    int i;
    SynthHandler synthHandler;

    template<SynthMode mode>
        void BlockTemplate( int );

    channel( int );
};

channel::channel(int mode)
{
    i = mode;
    printf("channel::channel mode=%u\n", mode );
    synthHandler = &channel::BlockTemplate< sm3FM >;
}

template<SynthMode mode>
void channel::BlockTemplate( int i1 )
{
    printf("channel::BlockTemplate, mode=%u, i1=%u\n", mode, i1 );
    switch ( mode ) {
    case sm2AM: break;
    case sm2FM: break;
    }
    return;
}

int main ( int arcc, char * *argv )
{
    channel *myobj = new channel(1);
    printf("obj=%p\n", myobj );
    myobj->i = 3;
    ( myobj ->* myobj->channel::synthHandler)(0);
    return( 0 );
}

Feeding OW's wcc386 with it emits:

tmpl.cpp(29): Error! E512: col(24) function address cannot be converted to pointer to class member
tmpl.cpp(29): Note! N630: col(24) source conversion type is 'void (channel::* )( int )'
tmpl.cpp(29): Note! N631: col(24) target conversion type is 'void (channel::* )( int )'

Which is a bit strange since source and targer don't differ. I'm no C++ expert, but I ran this test case with gcc, OW, Borland C++ v5.5.1 and the MS VC++ Toolkit 2003 - and it's just OW that chokes.

Attached is the test case, with .BATs how I ran the various compilers

tmpl.zip

jmalak commented 8 months ago

My knowledge for C++ is also limited. The OW C++ compiler is using very old C++ standard C++98 that some limitation can caused this message. I hope @pchapin will comment this issue.

pchapin commented 8 months ago

I think it's a compiler bug. Template members are one of the most recent additions to the Open Watcom C++ compiler and have some other limitations. Also, the compiler does not allow one to explicitly specialize function templates (contrary to C++ 98). Frankly, I'm surprised the example works as well as it does! The compiler seems to understand that channel::BlockTemplate<sm3FM> is an explicit specialization of a template member function. While that's legal C++, I wouldn't have expected Open Watcom to understand that.

So, yes, the compiler is confused... but not as confused as I would have thought!