UtkarshPramodGupta
UtkarshPramodGupta

Reputation: 8152

Threads creation in C

void print_hello_world() {
    pid_t pid = getpid();
    printf("Hello world %d\n", pid);
    pthread_exit(0);
}

void main() {
    pthread_t thread;
    pthread_create(&thread, NULL, (void *) &print_hello_world, NULL);
    print_hello_world();
}

I really couldn't understand what is the need of (void *) in pthread_create. And do we need "&print_hello_world" in the same or could drop "&" as I have read somewhere that while passing function pointers we don't need to place "&" before the function name.

Upvotes: 1

Views: 597

Answers (2)

too honest for this site
too honest for this site

Reputation: 12263

Casting a function pointer to/from void * is actually undefined behaviour. See 6.3.2.3, especially p1 and p8. Note that functions are no objects in C.

So the cast is wrong in fact and the addressof-operator & is unnecessary. You can cast, however, one function pointer to another (see §8 of the reference). But here, you shoud definitively have a proper signature for your function, as there is a reason it takes a pointer and returns one, too. So: do not cast, but get the signature (and semantics) correct.

Note: An empty identifier-list in a function declaration which is part of the definition is an obsolescent feature. Using the prototype-style (void) for an empty argument list is recommended. Also the minimal required signature for main is int main(void) (with respect to the above said).

Upvotes: 2

P.P
P.P

Reputation: 121387

Yes, there's no need for cast or & operator there:

pthread_create(&thread, NULL, print_hello_world, NULL);

should suffice as a function name gets converted into a function pointer when passing as argument to function(s).

Note that the function pointer you pass to pthread_create() takes a void* as argument and returns a void *. So your function should be:

void* print_hello_world(void *unused) {
...
}

It's the C way of implementing "generic" data type. For example, you can pass a int* or struct args* to the thread function and retrieve it back. E.g.

 int i=5;
 pthread_create(&thread, NULL, print_hello_world, &i); 

and in the function print_hello_world(), you would do:

void *print_hello_world(void *value) {
  int i = *(int*)value;
  ... 
}

Basically void* allows you to pass any data pointer to the thread function here. If pthread_create()'s thread function were to take int*, you wouldn't be able to pass a struct args* to it, for example.

I suggest you read the following posts for more information on void pointer and its usage in C:

Concept of void pointer in C programming and What does void* mean and how to use it?

Upvotes: 3

Related Questions