You need to cast void* pointer to the function pointer first:

#include <stdio.h>

typedef struct {
    void* fn;
    void* param;
} event;

void print()
{
        printf("Hello\n");
}


int main()
{
    event e;
        e.fn = print;
        ((void(*)())e.fn)();
        return 0;
}

Of course, if this is really what you want. If you want your struct to contain pointer to the function, instead of void* pointer, use the proper type at the declaration:

typedef struct {
    void (*fn)();
    void* param;
} event;

Here you have fn declared as a pointer to the void function, and the param as void* pointer.

Answer from Nemanja Boric on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › c language › void-pointer-c-cpp
void Pointer in C - GeeksforGeeks
If you're looking to master pointers, including how they work with data structures, the C Programming Course Online with Data Structures covers pointers extensively with practical use cases. ... The following program doesn't compile. ... // C Program to demonstrate that a void pointer // cannot be dereferenced #include <stdio.h> int main() { int a = 10; void* ptr = &a; printf("%d", *ptr); return 0; }
Published   July 17, 2014
🌐
GNU
gnu.org › software › c-intro-and-ref › manual › html_node › Void-Pointers.html
Void Pointers (GNU C Language Manual)
{ int *p; /* Converts return value to int *. */ p = numbered_slot_pointer (5); … } Passing an argument of type void * for a parameter that has a pointer type also converts. For example, supposing the function hack is declared to require type float * for its parameter, this call to hack will convert the argument to that type.
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_void_pointer.htm
void Pointer in C
A void pointer in C is a type of pointer that is not associated with any data type. A void pointer can hold an address of any type and can be typecasted to any type. They are also called general-purpose or generic pointers. In C programming, the function malloc() and calloc() return "void *" ...
🌐
Tufts University
cs.tufts.edu › comp › 40 › docs › function-pointers.html
Tufts: CS 40 Void and Function Pointers
Preamble: There are 3 unrelated meanings in C for the keyword void: As function return type: this function has no return value. As function parameter list in a declaration: this function takes exactly zero parameters. This is not the same as an empty parameter list — that means takes an unspecified number of parameters.! As the target of a pointer: The pointer is generic, there is no information about what it points to.
🌐
Deardevices
deardevices.com › 2019 › 05 › 07 › void-pointers-part1
3 Practical Uses of void Pointers in the C Language (part 1/3)
The qsort function is for sorting arrays of any type. The following snippet shows its signature: void qsort(void * base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); This actually demonstrates two different uses of void pointers. The function expects base to be the start of the array to be sorted.
🌐
Reddit
reddit.com › r/c_programming › void function pointer
r/C_Programming on Reddit: Void function pointer
January 5, 2024 -

As far as i understood void(*)() works in a similiar way void* works, but with function pointers, meaning you can cast any function pointer to it and back. Is this correct? However, i ran into a strange issue.

void foo(int i) {

}

void bar(char c) {

}

void test(void(*)()) {

}

int main() {

test(foo);


//test(bar); compile error

}

I get an incompatible pointer type error if i try to pass a function with param char, but it works with param int, why would that be? Thanks!

I apologize for the formatting, writing from my phone.

Top answer
1 of 5
19
meaning you can cast any function pointer to it and back I think there's a misunderstanding here. You can do that with any function pointer type, void(*)() isn't special here. From C99: A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined. Note that these conversions might require a cast. There's also no special provisions for void(*)() to make it implicitly convertible with everything like there is for void*. The reason why your example works the way it does is that void(*)(int) is implicitly convertible to void(*)(), because they're pointers to compatible function types. The relevant passage is: If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. So because the default argument promotions turn char into int, void(*)(char) is not convertible, but void(*)(int) is.
2 of 5
5
void(*)() is not the same as void* - it's not just a generic function pointer that is compatible with all other function pointers. You can still cast the function pointer to a different pointer type, but you have to cast it explicitly. It's not automatically compatible. I think this part of the standard is what makes it complain: https://port70.net/%7Ensz/c/c11/n1570.html#6.7.6.3p15 specifically the part about "the type of each parameter shall be compatible with the type that results from the application of the default argument promotions". A char is promoted to an int and so your function needs to have an int argument in that position.
Top answer
1 of 4
12

You need to cast void* pointer to the function pointer first:

#include <stdio.h>

typedef struct {
    void* fn;
    void* param;
} event;

void print()
{
        printf("Hello\n");
}


int main()
{
    event e;
        e.fn = print;
        ((void(*)())e.fn)();
        return 0;
}

Of course, if this is really what you want. If you want your struct to contain pointer to the function, instead of void* pointer, use the proper type at the declaration:

typedef struct {
    void (*fn)();
    void* param;
} event;

Here you have fn declared as a pointer to the void function, and the param as void* pointer.

2 of 4
2

event is a type, not an object or expression. You can't access a member of a structure type, only of an object of a structure type.

So given:

typedef struct {
    void* fn;
    void* param;
} event;

you need to have an object of type event, and you need to assign values to its members.

In your question, you use fn as a member name, but then you refer to something called function. I'll assume here that they're supposed to be the same thing, and that fn is supposed to point to some function.

You can't portably store a function pointer in a void*. On many, probably most, implementations you can get away with it, but it's not guaranteed by the language. (There are systems were function pointers are bigger than data pointers, and converting a function pointer to void* loses information.) On the other hand, all pointer-to-function types are convertible to each other, and a round-trip conversion is guaranteed to give you the original pointer value.

I'll assume (I'm making a lot of assumptions here because you didn't provide a lot of information) that you want fn to point to a function that takes a void* argument and doesn't return a result; then making param a void* makes sense. For consistency with that assumption, we can alter your type definition:

typedef struct {
    void (*fn)(void*);
    void *param;
} event;

(The void (*fn)(void*); syntax is not entirely obvious. I used cdecl to construct it.)

Now you can define an object of type event:

event e = { some_func, NULL };

You have to have defined some_func somewhere, as

void some_func(void *param { /* ... */ }

or equivalent. Now you can call that function indirectly through the event object e:

e.fn(e.param);

Or, if it's more convenient to have a pointer to an event:

event *ptr = malloc(sizeof *ptr);
if (event == NULL) {
    /* error handling here */
}
ptr->fn = some_func;
ptr->param = NULL;

and you can use indirection both on the pointer-to-event and on the function pointer contained in the event object it points to:

ptr->fn(ptr->param);

Depending on what you're trying to accomplish, you might want fn to be able to point to functions of different types. If you do that, you must convert (with an explicit cast) e.fn or ptr->fn to the actual type of the function it points to before making a call through it. You can't blindly mix function pointers of different types; if you do, the result is either a compile-time error or run-time undefined behavior. You can use void (*)(void) (pointer to function with no parameters and returning no result) as a "generic" function pointer type, but unlike with void* any conversions to the type you need must be explicit.)

I want to know how to make the function call both with and without using the additional void* param.

To call a function with no argument, simply use () in the function call. But again, for a given function, you can't choose to call it with or without a parameter; the call has to match the definition. (Except perhaps for variadic functions like printf, but you still need a function pointer of the correct type, and a variadic function can't be called with no arguments.)

🌐
HackerEarth
hackerearth.com › practice › notes › void-pointer-in-c
void pointer in C | HackerEarth
A void pointer is a pointer that has no associated data type with it. A void pointer can hold address of any type and can be typcasted to any type. int a = 10; char b = 'x'; void *p …
Find elsewhere
Top answer
1 of 11
253

A pointer to void is a "generic" pointer type. A void * can be converted to any other pointer type without an explicit cast. You cannot dereference a void * or do pointer arithmetic with it; you must convert it to a pointer to a complete data type first.

void * is often used in places where you need to be able to work with different pointer types in the same code. One commonly cited example is the library function qsort:

void qsort(void *base, size_t nmemb, size_t size, 
           int (*compar)(const void *, const void *));

base is the address of an array, nmemb is the number of elements in the array, size is the size of each element, and compar is a pointer to a function that compares two elements of the array. It gets called like so:

int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);

The array expressions iArr, dArr, and lArr are implicitly converted from array types to pointer types in the function call, and each is implicitly converted from "pointer to int/double/long" to "pointer to void".

The comparison functions would look something like:

int compareInt(const void *lhs, const void *rhs)
{
  const int *x = lhs;  // convert void * to int * by assignment
  const int *y = rhs;

  if (*x > *y) return 1;
  if (*x == *y) return 0;
  return -1;
}

By accepting void *, qsort can work with arrays of any type.

The disadvantage of using void * is that you throw type safety out the window and into oncoming traffic. There's nothing to protect you from using the wrong comparison routine:

qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);

compareInt is expecting its arguments to be pointing to ints, but is actually working with doubles. There's no way to catch this problem at compile time; you'll just wind up with a missorted array.

2 of 11
30

Using a void * means that the function can take a pointer that doesn't need to be a specific type. For example, in socket functions, you have

send(void * pData, int nLength)

this means you can call it in many ways, for example

char * data = "blah";
send(data, strlen(data));

POINT p;
p.x = 1;
p.y = 2;
send(&p, sizeof(POINT));
🌐
Javatpoint
javatpoint.com › void-pointer-in-c
Void Pointer in C - javatpoint
A Null Pointer is a pointer that does not point to any memory location. It stores the base address of the segment. The null pointer basically stores the Null value while void is the type of the pointer. A null pointer is a... ... Till now, we have seen that in C programming, we can pass the ...
Top answer
1 of 4
4

You can write a perfectly fine generic function this way, but:

    result = array[rand()%(length-1)];

This is dereferencing the void pointer array while also attempting to store it into a pointer result. What you want to store is the address at that offset:

    result = array + rand()%(length-1);

However, you can't perform arithmetic like this on void pointers either, as the size of the underlying type is not known (some compilers allow sizeof(void)==1 as an extension). With a non-void array, the number of bytes a given element consumes, and thus the number of bytes to increment by when doing arithmetic on the address, is encoded in the type. In a generic function operating on void pointers like this one you'll need to explicitly pass the size of the type.

void *randomNum(void * array, size_t size, size_t length)

Now perform the calculation by casting array to a char pointer, which forces arithmetic on array to occur in increments of 1 byte times the provided size parameter:

    result = (char*)array + (rand()%(length-1)) * size;
                   ^                            ^

You can then call randomNum with randomNum(array, sizeof(*array), 9)

However, you still need to cast the return value of the function before dereferencing it.

    printf("%d\n", *(int*)randomNum(array,sizeof(*array),9));
2 of 4
2

There are a number of problems with the approach:

1) Since the argument array is of type void *, your plan of indexing it based on length will not work—for indexing to work, the length of each element in your array needs to be known as well. You seem to be trying to make a generic function that would work for any type of array, but honestly it's simpler to make a separate function for different types of arrays.

(To see why this is problematic, remember that array[index] is equivalent to *(array + index); by indexing the void * you are applying pointer arithmetic to and then dereferencing the void pointer. Meditate on this.)

2) You are dereferencing a void pointer when you do *randomNum(array, 9). This cannot be done; you need to cast the pointer to an appropriate type first, i.e., *((int *)randomNum(array, 9)), but as I said above, the whole approach with randomNum dealing in void pointers is problematic, so just change the whole thing to:

int *randomNumInt(int *array, size_t length)
🌐
OverIQ
overiq.com › c-programming-101 › void-pointers-in-c
Void Pointers in C - C Programming Tutorial - OverIQ.com
A void pointer can point to a variable of any data type and void pointer can be assigned to a pointer of any type.
🌐
BYJUS
byjus.com › gate › void-pointer-in-c
Void Pointer in C
August 1, 2022 - The void pointer in C is a pointer that is not associated with any data types. It points to some data location in the storage. This means that it points to the address of variables.
🌐
Reddit
reddit.com › r/c_programming › how do i cast a void* to function pointer?
r/C_Programming on Reddit: How do I cast a void* to function pointer?
June 13, 2020 -

So I want to be able to store 2 types of functions in an array: one that returns an int and one that doesn't return anything.

int add(int x, int y) {
    return x + y;
}

void foo() {
    printf("foo\n");
}

static void* funcs[] = {add, foo};

My question is, how do I then cast the first pointer to a function pointer so I can call it? Same for the second.

🌐
PrepBytes
prepbytes.com › home › c programming › void pointer in c
Void Pointer in C
January 8, 2024 - The function accepts two void pointers, ‘ptr1’ and ‘ptr2’, and a size_t variable ‘size’ that specifies the size of the data being swapped. The function allocates memory for a temporary variable ‘temp’, and uses the memcpy() function to copy the data pointed to by ‘ptr1’ to ‘temp’. The function then copies the data pointed to by ‘ptr2’ to ‘ptr1’, and the data pointed to by ‘temp’ to ‘ptr2’. Finally, the function frees the memory allocated for ‘temp’.
🌐
Stanford
web.stanford.edu › class › archive › cs › cs107 › cs107.1202 › lab4
CS107 Lab 4: void * and Function Pointers
Referring to data by address is fundamental to how C supports generic functions. Sending or receiving an actual value is not possible because the values vary in type/size. Instead what is exchanged are pointers to values. All pointers, regardless of pointee, are 8-byte addresses that are type-compatible with void*.
🌐
Uwinnipeg
theory.uwinnipeg.ca › programming › node87.html
Void pointers
"); scanf("%c", &ans); if (ans == 'i') { p = &i_age; greeting(use_int, p); } else { p = &f_age; greeting(use_float, p); } return 0; } void greeting(void (*fp)(void *), void *q) { fp(q); } void use_int(void *r) { int a; a = * (int *) r; printf("As an integer, you are %d years old.\n", a); } void use_float(void *s) { float *b; b = (float *) s; printf("As a float, you are %f years old.\n", *b); } Although this requires us to cast the void pointer into the appropriate type in the relevant subroutine (use_int or use_float), the flexibility here appears in the greeting routine, which can now handle in principle a function with any type of argument.
🌐
Scaler
scaler.com › topics › void-pointer-in-c
Void Pointer in C - Scaler Topics
October 18, 2022 - Void pointers can be used as a generic pointer, to store the address of different data types at different times · Void pointers are helpful in dynamic memory allocations, as functions like malloc() and calloc() return a void pointer, which can easily be typecasted into any type of pointer, meaning with the help of void pointers, it is made possible for the functions like malloc() and calloc() to allocate memory to any datatype without doing any additional typecasting, because they can simply always written a void pointer, and then the user can typecast it as per their requirement
🌐
Rip Tutorial
riptutorial.com › void* pointers as arguments and return values to standard functions
C Language Tutorial => void* pointers as arguments and return...
The pointer-to-void return type means that it is possible to assign the return value from malloc to a pointer to any other type of object: ... It is generally considered good practice to not explicitly cast the values into and out of void pointers.
Top answer
1 of 2
3

The declaration is read as follows:

        function        -- function is a 
       *function        -- pointer to 
      (*function) ()    -- function taking unspecified parameters
     *(*function) ()    -- returning pointer to
void *(*function) ();   -- void

So, function is a pointer to a function type, not a function itself. You could have multiple functions, each returning pointers to void:

void *foo( void )    { ... }
void *bar( void )    { ... }
void *bletch( void ) { ... }

You can use the function pointer to point to each of those functions, and decide at runtime which to call:

if ( condition1 )
  function = foo;
else if ( condition2 )
  function = bar;
else
  function = bletch;

void *ptr = function(); // or (*function)();
2 of 2
2

The notation

void * (*function)();

means “declare a function pointer named function, which points to a function that takes an unspecified number of arguments, then returns a void *.”

Since this just declares a variable, it doesn’t define a function and so nothing can be said about what value is going to be returned. You’d need to assign this pointer to point to a function before you can call it.

Once you do assign function to point to something, if you call function, you’ll get back a void *, which you can think of as “a pure memory address” since it contains an address but can’t be dereferenced to an object without a cast.

Notice that returning a void * is not the same as as a function that has a void return type. The former means “I return a memory address,” and the latter means “I don’t return anything at all.”