I have come across the line of code shown below.
I think it may be a cast to a function pointer that returns void and takes a void pointer. Is that correct?
Yes, it is. The function should be looking like this
void func(void*);
But the statement is missing a target, since a cast to nothing is useless. So it should be like
func = (void (*)(void *))SGENT_1_calc;
Yes, it is correct. I find that not very readable, so I suggest declaring the signature of the function to be pointed:
typedef void sigrout_t(void*);
I also have the coding convention that types ending with rout_t
are such types for functions signatures. You might name it otherwise, since _t
is a suffix reserved by POSIX.
Later on I am casting, perhaps to call it like
((sigrout_t*) SGENT_1_calc) (someptr);
Yes, this is a function pointer cast.
To help you with casting functions to pointers, you can define an alias for a function pointer type as follows:
typedef void void_to_void_fct(void*);
You can also define a type for a function that takes and returns values:
typedef int math_operator(int, int);
Later, you can store a function into a function pointer type like this:
void mystery(void* arg) {
// do something nasty with the given argument
};
int add(int a, int b) {
return a + b;
}
void_to_void *ptr1 = mystery;
math_operator *ptr2 = add;
Sometimes, you have a function like print_str
:
void print_str(char* str) {
printf("%s", str);
}
and you want to store it in your function pointer that is agnostic to the argument type. You can then use a cast like this:
(void (*)(void *))print_str
or
(void_to_void_fct*)print_str
Function pointers allow you to "store a function" inside a variable (indeed, you store the address of the function). This is very convenient when you want to allow some code to have diferent behavior depending on user input.
For exemple, suppose we have some data and some way to decode it. We could have the following structure to keep this information:
typedef char* decoder_type(char*);
struct encoded_data {
char* data;
decoder_type *decoder_fct;
};
char* decoding_function_1(char* data) {
//...
char* decoding_function_2(char* data) {
//...
This allows storing both the data and the function to later use them together to decode the data.