简体   繁体   中英

compile error only when passing capture var in labda to pthread_create

In the code below, I am having pthread_create call a class function using lambdas (same can be done with a function pointer). The first two compile ok, but the third gives a compile error that looks like trying to convert a pointer to a class member to a C-type function. Not sure.

#include <pthread.h>


class threadtest
{
private:
    void* thread1()            { return nullptr; }
    void* thread2( void* p )   { return p;       }


public:
    void start();
};

void threadtest::start()
{
   pthread_t thd0;
   auto fn0 = []( void* a_pArg ) -> void* { return static_cast<threadtest*>( a_pArg )->thread1(); };
   pthread_create( &thd0, NULL, fn0, (void*)this );

   pthread_t thd1;
   auto fn1 = []( void* a_pArg ) -> void* { void* p = nullptr; return static_cast<threadtest*>( a_pArg )->thread2( p ); };
   pthread_create( &thd1, NULL, fn1, (void*)this );

   pthread_t thd2;
   void* p;
   auto fn3 = [p]( void* a_pArg ) -> void* { return static_cast<threadtest*>( a_pArg )->thread2( p ); };
   pthread_create( &thd2, NULL, fn3, (void*)this );
}

Here is the error:

threadtest.cpp: In member function ‘void threadtest::start()’:
threadtest.cpp:31:50: error: cannot convert ‘threadtest::start()::__lambda2’ to ‘void* (*)(void*)’ for argument ‘3’ to 
‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
pthread_create( &thd2, NULL, fn3, (void*)this );

The compiler version is: gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

In my actual code I am not doing the second or 3rd example. I know there is a race condition on the var coming off of the stack while the thread gets access to it. I am just curious as to why the compiler throws an error when any var gets captured? What changes?

Thanks

Your lambda expression named fn3 captures the variable p . Only capture-less lambdas define a conversion to a function pointer.

Quoting N3337, §5.1.2/6 [expr.prim.lambda]

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type's function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type's function call operator.

Hence, when you attempt to convert the lambda into a function pointer in the call to pthread_create it fails.


The reason this is disallowed is that there is no way for a function pointer to carry along the state that has been captured by the lambda.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM