Pointers to non-static member functions, compiles with MSDEV, but not with GCC

Discussion in 'C++' started by John Doe, Oct 23, 2003.

  1. John Doe

    John Doe Guest

    #include "project.h"


    class ThatDoesProcessing;
    typedef int (ThatDoesProcessing::*PFUNC)(int);


    class ThatDoesProcessing {

    public:

    int ProcessThis( PFUNC pFunc ) {

    int iRet = (this->*pFunc)( 2 );

    return iRet;

    }

    };


    class ThatNeedsToBeProcessed : public ThatDoesProcessing {

    public:

    void Test( void ) {

    PFUNC pMyFunc;

    pMyFunc = (PFUNC)CompareFunc;

    ProcessThis( pMyFunc );

    }

    int CompareFunc( int i ) {

    return i;

    }

    };


    int _tmain( int /* argc */, TCHAR * /* argv[] */ ) {

    ThatNeedsToBeProcessed b;

    b.Test();

    return 0;

    }

    ---------------------------------------------------
    The above compiles without any warnings or errors at all even
    with warning level set to 4 with the MS compiler.

    Compliling it with GCC version 3.3.1 (cygming special)
    gives the following output:

    $ make
    g++ -O2 -fno-strength-reduce -I/cygdrive/m/include -I/usr/X11R6/include
    -D__i386__ -DWIN32_LEAN_AND_MEAN -DX_LOCALE -D_X86_ -D__CYGWIN__
    -D_XOPEN_SOURCE -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE
    -D_SVID_SOURCE -D_GNU_SOURCE -c -o main.o main.cpp
    main.cpp: In member function `void ThatNeedsToBeProcessed::Test()':
    main.cpp:33: error: argument of type `int (ThatNeedsToBeProcessed::)(int)' does
    not match `int (ThatDoesProcessing::*)(int)'
    make: *** [main.o] Error 1

    ---------------------------------------------------

    The error is on the line which reads

    pMyFunc = (PFUNC)CompareFunc;

    in ThatNeedsToBeProcessed::Test

    I thought the whole idea of a cast was to coerce the compiler into seeing
    one type as another, so why does it refuse to do so here? How do I get
    around it?

    Thanks in advance.
     
    John Doe, Oct 23, 2003
    #1
    1. Advertising

  2. John Doe

    Ron Natalie Guest

    "John Doe" <> wrote in message news:p...

    >
    > I thought the whole idea of a cast was to coerce the compiler into seeing
    > one type as another, so why does it refuse to do so here? How do I get
    > around it?


    Even if it compiled (which it shouldn't), your code exhibits undefined behavior. There's no
    guarantee that it is going to work. You are not allowed to use the cast-bashed pointer
    value until you cast it back to what it was before. The cast here is a reinterpret cast
    and all you are guaranteed to be able to do is park the pointer value in the other pointer
    and then cast it back to what it was before before you use it (you can also check it
    against null).

    It shouldn't even compile. You don't form pointer to members like you wrote it.
    pMyFunc = reinterpret_cast<PFUNC>(&ThatNeedsToBeProcessed::CompareFunc);

    The fact that you even need the cast is telling. If this were to work nicely the implicit
    conversion would suffice. The problem is that not every member of the derived class
    is valid in base (and specifically this one isn't).

    How about a functor or something.
     
    Ron Natalie, Oct 23, 2003
    #2
    1. Advertising

  3. "John Doe" <> threw a soggy newspaper against the
    wall, and here's what stuck:

    >
    > The error is on the line which reads
    >
    > pMyFunc = (PFUNC)CompareFunc;
    >
    > in ThatNeedsToBeProcessed::Test
    >
    > I thought the whole idea of a cast was to coerce the compiler into
    > seeing one type as another, so why does it refuse to do so here? How
    > do I get around it?



    This seemed to do the trick for me:


    START CODE --

    // #include "project.h"
    #include <iostream>

    class ThatDoesProcessing;
    typedef int (ThatDoesProcessing::*PFUNC)(int);

    class ThatDoesProcessing
    {
    public:
    int ProcessThis( PFUNC pFunc ) {
    int iRet = (this->*pFunc)( 2 );
    return iRet;
    }

    virtual int CompareFunc( int i ) {
    std::cout << "Oops!" << std::endl;
    return 0;
    }

    };


    class ThatNeedsToBeProcessed : public ThatDoesProcessing
    {
    public:
    void Test( void ) {
    PFUNC pMyFunc;
    pMyFunc = &ThatDoesProcessing::CompareFunc;
    ProcessThis( pMyFunc );
    }

    virtual int CompareFunc( int i ) {
    std::cout << "Made it!" << std::endl;
    return i;
    }

    };


    // I eliminated the _tmain and TCHAR here so I could
    // build it.
    int main( int /* argc */, char * /* argv[] */ )
    {

    ThatNeedsToBeProcessed b;
    b.Test();
    return 0;
    }

    -- END CODE

    PMP
     
    Paul M. Parks, Oct 23, 2003
    #3
  4. Re: Pointers to non-static member functions, compiles with MSDEV, butnot with GCC

    John Doe escribió:

    > #include "project.h"
    >
    > class ThatDoesProcessing;
    > typedef int (ThatDoesProcessing::*PFUNC)(int);
    >
    > class ThatDoesProcessing {
    >
    > public:
    >
    > int ProcessThis( PFUNC pFunc ) {
    >
    > int iRet = (this->*pFunc)( 2 );
    >
    > return iRet;
    >
    > }
    >
    > };
    >
    > class ThatNeedsToBeProcessed : public ThatDoesProcessing {
    >
    > public:
    >
    > void Test( void ) {
    >
    > PFUNC pMyFunc;
    >
    > pMyFunc = (PFUNC)CompareFunc;


    pMyFunc= (PFUNC) & ThatNeedsToBeProcessed::CompareFunc;

    Regards.
     
    =?iso-8859-1?Q?Juli=E1n?= Albo, Oct 23, 2003
    #4
  5. John Doe

    Ron Natalie Guest

    "Paul M. Parks" <> wrote in message news:Xns941DA52E1CC1BDarthPaulOfDuluth@216.168.3.44...

    > This seemed to do the trick for me:
    >


    Much better...well formed and no undefined behavior.
     
    Ron Natalie, Oct 23, 2003
    #5
  6. John Doe

    lilburne Guest

    Re: Pointers to non-static member functions, compiles with MSDEV,but not with GCC

    Ron Natalie wrote:

    > "Paul M. Parks" <> wrote in message news:Xns941DA52E1CC1BDarthPaulOfDuluth@216.168.3.44...
    >
    >
    >>This seemed to do the trick for me:
    >>

    >
    >
    > Much better...well formed and no undefined behavior.
    >


    The msdev compiler accepts a whole load of nonesense which
    it ought to complain about. An example is:

    int ff() {
    return 0;
    }

    int main()
    {
    if (ff) { // this ought to have been 'if (ff()) {'
    return 1;
    }
    return 0;
    }
     
    lilburne, Oct 23, 2003
    #6
  7. John Doe

    lilburne Guest

    Re: Pointers to non-static member functions, compiles with MSDEV,but not with GCC

    jeffc wrote:

    > "lilburne" <> wrote in message
    > news:bn9fh5$v9uis$-berlin.de...
    >
    >>The msdev compiler accepts a whole load of nonesense which
    >>it ought to complain about. An example is:
    >>
    >>int ff() {
    >> return 0;
    >>}
    >>
    >>int main()
    >>{
    >> if (ff) { // this ought to have been 'if (ff()) {'
    >> return 1;
    >> }
    >> return 0;
    >>}

    >
    >
    > My current compiler allows that too.
    >


    Fortunately the sun solaris and irix compilers generate
    warnings. Try turning up the warning level on your compiler
    and force all warnings to be errors.
     
    lilburne, Oct 23, 2003
    #7
  8. John Doe

    jeffc Guest

    "lilburne" <> wrote in message
    news:bn9fh5$v9uis$-berlin.de...
    >
    > The msdev compiler accepts a whole load of nonesense which
    > it ought to complain about. An example is:
    >
    > int ff() {
    > return 0;
    > }
    >
    > int main()
    > {
    > if (ff) { // this ought to have been 'if (ff()) {'
    > return 1;
    > }
    > return 0;
    > }


    My current compiler allows that too.
     
    jeffc, Oct 23, 2003
    #8
  9. John Doe

    Ron Natalie Guest

    "lilburne" <> wrote in message news:bn9fh5$v9uis$-berlin.de...

    > The msdev compiler accepts a whole load of nonesense which
    > it ought to complain about. An example is:
    >
    > int ff() {
    > return 0;
    > }
    >
    > int main()
    > {
    > if (ff) { // this ought to have been 'if (ff()) {'


    Perfectly valid C++. ff is the address of the function. The statement is always true.
     
    Ron Natalie, Oct 23, 2003
    #9
  10. John Doe

    lilburne Guest

    Re: Pointers to non-static member functions, compiles with MSDEV,but not with GCC

    Ron Natalie wrote:

    > "lilburne" <> wrote in message news:bn9fh5$v9uis$-berlin.de...
    >
    >
    >>The msdev compiler accepts a whole load of nonesense which
    >>it ought to complain about. An example is:
    >>
    >>int ff() {
    >> return 0;
    >>}
    >>
    >>int main()
    >>{
    >> if (ff) { // this ought to have been 'if (ff()) {'

    >
    >
    > Perfectly valid C++. ff is the address of the function. The statement is always true.
    >


    It might be valid but it is never what was intended. Quite a
    few compilers generate a warning.
     
    lilburne, Oct 23, 2003
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    462
  2. dolphin
    Replies:
    3
    Views:
    1,403
    Pete Becker
    Dec 5, 2007
  3. Hicham Mouline
    Replies:
    0
    Views:
    456
    Hicham Mouline
    Apr 23, 2009
  4. Hicham Mouline
    Replies:
    1
    Views:
    443
    Michael DOUBEZ
    Apr 24, 2009
  5. paul
    Replies:
    8
    Views:
    744
    Alf P. Steinbach
    Apr 30, 2009
Loading...

Share This Page