The sample code will copy a and b twice, once to put them in the lambda closure
Only without optimization flags enabled. Otherwise the lambda will be inlined in most cases.
BZZT! Wrong! Think: what happens if a and b are local variables and the function creating the thread returns before the lambda runs? They must be copied to somewhere that is not destroyed by the caller returning. That copy is not in the correct location because they are created before the thread stack, so another copy is unavoidable. The only way to fix it is to make do_something take const references. Though it is true that if do_something was inline it would probably fix it.
Yes it is ugly and I never claimed otherwise. The problem is that C++ compiles into the equivalent of this and it is hidden behind the scenes. Here is is pretty obvious that I must not pass a pointer to a or b, not so clear in C++:
#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
void do_something(int a, int b) {
printf("do_something %d %d\n", a, b);
}
typedef struct {
int a, b;
} lambda_args;
void* lambda_run (void *p) {
lambda_args* v = (lambda_args*)p;
do_something(v->a, v->b);
free (v);
return 0;
}
void thread_do_something (int a, int b)
{
lambda_args* v = (lambda_args*)malloc(sizeof(lambda_args));
v -> a = a;
v -> b = b;
pthread_t thread;
pthread_create (&thread, 0, lambda_run, v);
}
int main()
{
thread_do_something(1, 2);
thread_do_something(3, 4);
sleep (1);
return 0;
}