Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does void *(*routine)(void *) mean in C? [duplicate]

I'm learning C and I came to this expression:

void *(*routine)(void *)

I find it very confusing. Maybe it's a pointer...to a pointer... to a pointer?

If I wanted to pass this thing into a function, how would we manipulate it? I am trying to pass this routine construction as a parameter to a function that takes a void(*)(void)... but I am rather lost on what that actually means.

like image 473
PinkElephantsOnParade Avatar asked Jan 28 '14 16:01

PinkElephantsOnParade


2 Answers

Start with the leftmost identifier and work your way out, remembering that absent explicit grouping with parentheses, [] and function call () bind before *, so

  • *a[N] is an N-element array of pointers
  • (*a)[N] is a pointer to an N-element array
  • *f() is a function returning a pointer
  • (*f)() is a pointer to a function

So,

        routine             -- routine
       *routine             -- is a pointer
      (*routine)(      )    -- to a function
      (*routine)(void *)    -- taking a single parameter of type void *
     *(*routine)(void *)    -- returning a pointer
void *(*routine)(void *)    -- to void
like image 140
John Bode Avatar answered Nov 15 '22 10:11

John Bode


void *(*routine)(void *);

declares a pointer to function that takes argument of type void * and returns pointer of type void *


Simple example:

#include <stdio.h>

void* foo(void* x) {
    printf("Hello.");
}

int main(void) {
    void *(*routine)(void *);
    routine = foo;              // assings foo to our function pointer
    (*routine)(NULL);           // invokes foo using this pointer
    return 0;
}

outputs: Hello.


"If I wanted to pass this thing into a function" ~ here is example 2 for you:

#include <stdio.h>

void* foo(void* x) {
    printf("Hello.");
}

typedef void *(*RoutinePtr)(void *);           // alias to make your life easier

void routineInvoker(RoutinePtr routine) {
    (*routine)(NULL); // invokes the routine
}

int main(void) {
    RoutinePtr routine = foo;   // creates a function pointer
    routineInvoker(routine);    // and passes it to our invoker
    return 0;
}
like image 20
LihO Avatar answered Nov 15 '22 08:11

LihO