Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Pointers to non-static member functions, compiles with MSDEV, but not with GCC

Reply
Thread Tools

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

 
 
John Doe
Guest
Posts: n/a
 
      10-23-2003


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

 
Reply With Quote
 
 
 
 
Ron Natalie
Guest
Posts: n/a
 
      10-23-2003

"John Doe" <> wrote in message news n...

>
> 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::C ompareFunc);

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.


 
Reply With Quote
 
 
 
 
Paul M. Parks
Guest
Posts: n/a
 
      10-23-2003
"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
 
Reply With Quote
 
=?iso-8859-1?Q?Juli=E1n?= Albo
Guest
Posts: n/a
 
      10-23-2003
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.
 
Reply With Quote
 
Ron Natalie
Guest
Posts: n/a
 
      10-23-2003

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

> This seemed to do the trick for me:
>


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


 
Reply With Quote
 
lilburne
Guest
Posts: n/a
 
      10-23-2003
Ron Natalie wrote:

> "Paul M. Parks" <> wrote in message news:Xns941DA52E1CC1BDarthPaulOfDuluth@216.168.3.4 4...
>
>
>>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;
}



 
Reply With Quote
 
lilburne
Guest
Posts: n/a
 
      10-23-2003
jeffc wrote:

> "lilburne" <> wrote in message
> news:bn9fh5$v9uis$...
>
>>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.

 
Reply With Quote
 
jeffc
Guest
Posts: n/a
 
      10-23-2003

"lilburne" <> wrote in message
news:bn9fh5$v9uis$...
>
> 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.


 
Reply With Quote
 
Ron Natalie
Guest
Posts: n/a
 
      10-23-2003

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

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


 
Reply With Quote
 
lilburne
Guest
Posts: n/a
 
      10-23-2003
Ron Natalie wrote:

> "lilburne" <> wrote in message news:bn9fh5$v9uis$...
>
>
>>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.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
code that compiles in c but not in c++? al.cpwn@gmail.com C Programming 7 04-03-2006 03:35 AM
Compiles with tolower from global namespace but not with std::tolower Eric Lilja C++ 4 09-02-2005 09:42 PM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM
compiles in g++ and .NET but not on VC6 !!! Julian C++ 12 12-21-2004 12:00 AM
Compiles in visual studio but not in g++ Mitch C++ 4 04-22-2004 06:40 AM



Advertisments