I was writing my own std::thread
-like wrapper for pthread_*
functions (for educational purposes). The constructor I came up with looked like this:
template<class Fn, class... Args>
explicit Thread(Fn&& fn, Args&&... args) {
using Invoker = Thread_invoker<Fn, Args...>;
void* (* start_fn)(void*) = [](void* invoker_ptr) -> void* {
// ...
};
auto invoker = std::make_unique<Invoker>(/* ... */);
const auto err = ::pthread_create(&handle_, nullptr, start_fn, invoker.get());
// ...
invoker.release();
}
I made some basic tests, the code works. But then it occurred to me that C++ functions can in theory have calling conventions that are different from C functions, and passing start_fn
function pointer to pthread_create
can be UB. This answer seems to confirm this.
Digging further, I found this question. Following the spirit of the accepted answer, I changed my code into this:
extern "C" using Thread_start_fn = void* (void*);
Thread_start_fn* start_fn = [](void* invoker_ptr) -> void* {
// ...
};
Does this modification solve the problem and is the code legal now?