warning: member functions are implicitly friends of their class

  • Thread starter Guenther Sohler
  • Start date
G

Guenther Sohler

Hallo,

I have written a very small testcase to try threads within classes

My code is following:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

class test
{
public:
test(void);
friend void *test::work_func(void *);
~test();
};

test::test(void)
{
pthread_t t;
printf("Constructor\n");
if(pthread_create(&t,NULL,work_func,NULL))
printf("No Thread created!\n");
}

void *test::work_func(void *)
{
while(1) printf("Working\n");
return NULL;
}

test::~test()
{
printf("Destructor\n");
}

int main(void)
{
test x;
sleep(1);
}

g++ -o testcase testcase.cpp -lpthread -Wall
testcase.cpp:9: warning: member functions are implicitly friends of their class


My goal is to get rid of the warning. And I want to keep the function
'work_func' within the class 'test'. How can I change the code to get it
clean ?

rds Guenther
 
K

Karl Heinz Buchegger

Guenther said:
Hallo,
[snip]


g++ -o testcase testcase.cpp -lpthread -Wall
testcase.cpp:9: warning: member functions are implicitly friends of their class

My goal is to get rid of the warning. And I want to keep the function
'work_func' within the class 'test'. How can I change the code to get it
clean ?

As the warning says. A member function already *has* access to all the internals
of that class. Thus there is no need to make it a friend.

class test
{
public:
test(void);
void *work_func(void *);
~test();
};
 
G

Guenther Sohler

Hallo,

Yes, this is an argument, but if I remove the friend keyword,
the type conversation from

void * test::work_func(void *)

to

void * work_func(void *)

does not work anymore.
Sorry, I forgot to mention this important issue before
 
R

Rob Williscroft

Guenther Sohler wrote in
Hallo,

Yes, this is an argument, but if I remove the friend keyword,
the type conversation from

void * test::work_func(void *)

to

void * work_func(void *)

does not work anymore.

Its unlikely it worked in the first place (If it did it would be a
very complex extension to standard C++).

You might get away making work_func a static member func, but even this
isn't truly portable as (IIUC) pthread_create expects a pointer to a C
function.


At global scope write:

extern "C" void *test_work_func( void * arg )
{
// if test::work_func() is now a static member you can do

test::work_func( p );

// if its a non-static member do

static_cast< test * >( p )->work_func();
}

test::test() now becomes:

test::test(void)
{
pthread_t t;
printf("Constructor\n");

// one of these NULL's presumably gets passes as the argument (p above)
// you'll need to change it to "this" if you make work_func a non-static
// member.

if(pthread_create(&t,NULL, test_work_func,NULL))
printf("No Thread created!\n");
}

HTH.

Rob.
 
G

Guenther Sohler

Hallo Rob,

After some tweeking and testing now I finally got it compiled without
warning. The very first testcode i sent in this thread actually compiled
with just a warning.

Unfortunately I do not understand, whats going on in the body of my
wrapper function.


void *wrapper(void *p)
{
return static_cast< test * >( p )->work_func(NULL);

}


Can you please tell me, what is actual c++ language, and what is
customizing ?
is static_cast < test * > a class template ?
Is it possible to write it in a way, in which the c++ compiler itself sees
it ( in c like typecast) eg (int *) ptr

rds
 
R

Rob Williscroft

Rob Williscroft wrote in 195.129.110.130:

Fowarded from email:
Hallo Rob,

After some tweeking and testing now I finally got it compiled without
warning. The very first testcode i sent in this thread actually
compiled with just a warning.

Unfortunately I do not understand, whats going on in the body of my
wrapper function.


void *wrapper(void *p)
{
return static_cast< test * >( p )->work_func(NULL);

}

I've posted a rewrite below. In it you will see I pass this as the
4th paramiter to pthread_create(,,, this ); the compiler does an
implicit conversion from test * (type of this expression) to void *.

Can you please tell me, what is actual c++ language, and what is
customizing ? is static_cast < test * > a class template ?

No its a cast (a language feature) its "safer" than a C style (test *)
cast in that it will never remove const qualifiers and it never does
a reinterpret_cast<> (reinterpret_cast<> is mostly bit copying).

lookup (internet/C++ reference book)
Is it possible to write it in a way, in which the c++ compiler itself
sees it ( in c like typecast) eg (int *) ptr

Thats what static_cast<> does and its less ambiguous than ((test*)p).
Though in this case both *are* equivalent.

code:
-----

#include <stdio.h>

class test
{
public:
test(void);
/* note no argument
*/
void *work_func();
~test();
};


/* from google

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg)
*/

/* for testing
*/

struct pthread_t {};
struct pthread_attr_t {};

int pthread_create(
pthread_t *thread,
pthread_attr_t const *attr,
void *(*start_routine)(void*),
void *arg
)
{
start_routine( arg );
return 0;
}


void *wrapper( void *that )
{
return static_cast< test * >( that )->work_func();
}


test::test(void)
{
pthread_t t;

printf("Constructor\n");

if ( pthread_create( &t, NULL, wrapper, this) )
{
printf("No Thread created!\n");
}
}

void *test::work_func()
{
for ( int i = 0; i < 10; ++i ) printf("Working\n");
return NULL;
}

test::~test()
{
printf("Destructor\n");
}

int main(void)
{
test x;
}

Rob.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top