warning: member functions are implicitly friends of their class

Discussion in 'C++' started by Guenther Sohler, Dec 1, 2003.

  1. 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
     
    Guenther Sohler, Dec 1, 2003
    #1
    1. Advertising

  2. Guenther Sohler wrote:
    >
    > 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();
    };

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Dec 1, 2003
    #2
    1. Advertising

  3. 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
     
    Guenther Sohler, Dec 1, 2003
    #3
  4. Guenther Sohler wrote in news:p:

    > 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.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Dec 1, 2003
    #4
  5. 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
     
    Guenther Sohler, Dec 2, 2003
    #5
  6. Rob Williscroft wrote in news:Xns9444B766A3926ukcoREMOVEfreenetrtw@
    195.129.110.130:

    Fowarded from email:

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

    >



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

    The static_cast< test * >( p ) above reverses this conversion back
    from void * to test *.

    >
    > 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)
    static_cast<>, const_cast<> reinterpret_cast<> and dynamic_cast<>.

    > 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.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Dec 2, 2003
    #6
  7. Guenther Sohler

    anthius

    Joined:
    Oct 7, 2006
    Messages:
    1
    This suggestion by Rob worked wonderfully for me. Thank you.
     
    anthius, Oct 7, 2006
    #7
    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. Raf256
    Replies:
    2
    Views:
    2,027
    Victor Bazarov
    Apr 15, 2005
  2. lovecreatesbeauty
    Replies:
    7
    Views:
    581
    lovecreatesbeauty
    May 12, 2005
  3. Replies:
    2
    Views:
    607
  4. Replies:
    0
    Views:
    666
  5. Dan Smithers

    private member functions as friends

    Dan Smithers, Jul 7, 2008, in forum: C++
    Replies:
    3
    Views:
    600
    Dan Smithers
    Jul 9, 2008
Loading...

Share This Page