Please tell me what will the call to given function return and how? The code:
typedef struct {
int size;
ptrdiff_t index;
void (*inlet) ();
int argsize;
ptrdiff_t argindex;
} CilkProcInfo;
/*
* Returns a pointer to the slow version for a procedure
* whose signature is p.
*/
/* the function definition is - */
static void (*get_proc_slow(CilkProcInfo *p)) () {
return p[0].inlet;
}
/*The function gets called as -*/
(get_proc_slow(f->sig)) (ws, f);
/*where f->sig is a pointer to CilkProcInfo struct*/
In your CilkProcInfo structure, inlet is a pointer to a function that takes an unspecified number of arguments and does not return a value, like void foo();.
In the line
(get_proc_slow(f->sig)) (ws, f);
the get_proc_slow(f->sig) call returns this function pointer, so it is equivalent to
(f->sig[0].inlet) (ws, f);
So if your f->sig[0].inlet points to the function foo(), it is equivalent to the call
foo (ws, f);
I should admit that the static void (*get_proc_slow(CilkProcInfo *p)) () {... syntax is a bit unfamiliar to me.
get_proc_slow() returns a function pointer of type void(*)() which the code then calls. So when you do:
(get_proc_slow(f->sig)) (ws, f);
It's basically same as doing:
void (*fptr)() = get_proc_slow(f->sig);
fptr(ws, f);
It looks like it's a function that returns a pointer to a function whose return value is void that has no parameters (void(*)()) and that accepts a pointer to a CilkProcInfo struct as a parameter. I'm not sure why you'd need the p[0].inlet construct though. Couldn't you just return it as p->inlet?
Oh yeah, and get_proc_slow is the name of the function that returns said function pointer.
static void (*get_proc_slow(CilkProcInfo *p)) () {
return p[0].inlet;
}
Reading from the name out, taking care with the grammar rules: get_proc_slow is a function (with internal linkage) that takes a pointer to a CilkProcInfo struct and returns a pointer to a function taking unspecified arguments and returning no value (void).
(get_proc_slow(f->sig)) (ws, f);
This statement calls the get_proc_slow with an appropriate parameter (f->sig is a pointer to a CilkProcInfo) and then uses the return value (a pointer to a function) to call that function with ws and f as arguments.
Related
I was reading this code on a website. I am fairly new to programming so please explain in a bit more detail.
#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a)
{
printf("Value of a is %d\n", a);
}
int main()
{
// fun_ptr is a pointer to function fun()
void (*fun_ptr)(int) = &fun;
/* The above line is equivalent of following two
void (*fun_ptr)(int);
fun_ptr = &fun;
*/
// Invoking fun() using fun_ptr
(*fun_ptr)(10);
return 0;
}
Doubts-
I am not able to understand this type of declaration and assignment void (*fun_ptr)(int) = &fun;
I mean that if we declare a data type, then we do it like int a; and assign it as a=10; but here we are assigning it by writing (*fun_ptr)(10);. Kindly help.
Instead of this record
(*fun_ptr)(10);
you could just write
fun_ptr(10);
That is it is a function call of the function fun pointed to by the function pointer fun_ptr due to the initialization of that pointer in its declaration by the function address
void (*fun_ptr)(int) = &fun;
In turn this declaration could be written simpler like
void (*fun_ptr)(int) = fun;
because a function designator (in this case fun) used in expressions as for example an initializer is implicitly converted to pointer to the function.
You could use a typedef alias for the function type the following way
typedef void Func( int );
In this case the above declaration of the function pointer could look simpler like
Func *fun_ptr = fun;
Here is your program rewritten using a typedef for the function type of the function fun.
#include <stdio.h>
typedef void Func( int );
// Function declaration without its definition using the typedef
// This declaration is redundant and used only to demonstrate
// how a function can be declared using a typedef name
Func fun;
// Function definition. In this case you may not use the typedef name
void fun( int a )
{
printf("Value of a is %d\n", a);
}
int main(void)
{
// Declaration of a pointer to function
Func *fun_ptr = fun;
// Call of a function using a pointer to it
fun_ptr( 10 );
return 0;
}
Lets rewrite it a little bit, by using type-aliases and some comments:
// Define a type-alias names fun_pointer_type
// This type-alias is defined as a pointer (with the asterisk *) to a function,
// the function takes one int argument and returns no value (void)
typedef void (*fun_pointer_type)(int);
// Use the type-alias to define a variable, and initialize the variable
// This defines the variable fun_ptr being the type fun_pointer_type
// I.e. fun_ptr is a pointer to a function
// Initialize it to make it point to the function fun
fun_pointer_type fun_ptr = &fun;
// Now *call* the function using the function pointer
// First dereference the pointer, to get the function it points to
// Then call the function, passing the single argument 10
(*fun_ptr)(10);
Hopefully it makes things a little clearer what's going on.
Following is the meaning of two statments.
void (*fun_ptr)(int) = &fun; this is called declaring and initializing the fun_ptr in the same line , this is same as doing int a = 10;
(*fun_ptr)(10); is not assignment statement, it is invoking the function fun through function pointer fun_ptr.
you can also use typedef to create a new user defined out of function pointer and use as shown in above answer.
This is an advanced topic if you are new to programming, fun_ptr is a pointer to a function.
The declaration:
void (*fun_ptr)(int) = fun;
Means fun_ptr is a pointer to a function taking an int argument and returning void, initialize if with a pointer to the function fun. (you don't need the &)
The line:
(*fun_ptr)(10);
does not assign anything, it calls the function pointed to by fun_ptr, but is way to complex
fun_ptr(10);
As fun_ptr points to fun this is equivalant to `fun(10).
Using a function pointer has its use eg in a sort function where the comparison function is passed in as a function pointer so the sorting can be different between calls.
achieves the same thing and is much easier on the eyes.
1) I am currently trying to understand the following code, but I can't understand what void(*func)(void) means, I can understand that I am trying to save a the address of function named "function" from list0513, at void pointer func, but what does the casting (void) just before the equal sign mean?
// list0513.c
#include <dlfcn.h>
int main(void)
{
void *handle = dlopen("./list0513.so", RTLD_LAZY);
void (*func)(void) = dlsym(handle, "function");
(*func)();
dlclose (handle);
return 0;
}
According to the book, the function called "function" is called from the following script
// list0513dl.c
#include <stdio.h>
void function(void)
{
printf("Hello World\n");
}
2) but how do I make a list0513.so file? the only files I've made are .c files...
Thanks for reading this.
The declaration reads as follows:
func — func
*func — is a pointer to
(*func)( ) — a function taking
(*func)(void) — no parameters
void (*func)(void) — returning void
The func pointer is then initialized with the result of the dlsym call, which returns the address of the function ”function” in the library list0513.so.
General declaration rules for pointer types:
T *p; // p is a pointer to T
T *p[N]; // p is an array of pointer to T
T (*p)[N]; // p is a pointer to an array of T
T *f(); // f is a function returning a pointer to T
T (*f)(); // f is a pointer to a function returning T
In both declarations and expressions, the postfix [] subscript and () function call operators have higher precedence than unary *, so *f() is parsed as *(f()) (function returning pointer). To declare a pointer to an array or function, the * has to be explicitly grouped with the array or function declarator.
Declarations can get pretty complex - you can have an array of pointers to functions:
T (*a[N])(); // a is an array of pointers to functions returning T
or functions returning pointers to arrays:
T (*f())[N]; // f is a function returning a pointer to an array
or even pointers to arrays of pointers to functions returning pointers to arrays:
T (*(*(*a)[N])())[M];
You probably won’t see anything that hairy in the wild, though (unless you run across some old code of mine).
It is omitted a declare of function type. The full or expended version should like this:
// list0513.c
#include <dlfcn.h>
int main(void)
{
void *handle = dlopen("./list0513.so", RTLD_LAZY);
typedef void(*FUNC)();
FUNC func = dlsym(handle, "function");
func(); // call function
dlclose (handle);
return 0;
}
Is such declaration void *(*function) () is valid ?
If it is valid then *function will return any address to called function .
At that address, what value is returning?
Is value save at that address is 0. If it is zero,what is the difference between return 0 and return nothing in function having return type void.
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)();
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.”
calling a function by a pointer which hold the address of the function is generating error
code:
p=GetProcAddress(h,"installhook");//p is a pointer that holds the address returned from getprocaddress() function
(*p)(); //using this pointer making a call to installhook function
but the code is generating error wher i am making a call by (*p)(); it says term does not evaluate to a function.
how doi overcome with this?is there any other way making a call to the function using pointer?
You need to cast the return value of GetProcAddress to the correct function type. For example:
typedef void (*FuncPtr)(); //assuming a function like void f()
FuncPtr p;
p = (FuncPtr) GetProcAddress(h, "funcName");
if (p)
p();
else
printf("Function not found\n");
Verify p is declared like this:
void (*p)(void);
and that the type of the return value of GetProcAddress is the same.
The code states:
void (* log_msg)(char *msg)
=printf;
void change_and_log(int *buffer, int offset, int value){
buffer[offset] = value;
log_msg("changed");
}
I'm most concerned with the first part:
Firstly, what does the signature void (* log_msg)(char *msg) mean? Is this code simply mapping the function log_msg to printf? In that case, why is the function name (* log_msg) and not simply log_msg?
void (* log_msg)(char *msg) is actually a function pointer. You could view this as
typedef void (*LoggerFunctionPointer)(char* msg);
LoggerFunctionPointer log_msg = printf;
Yes, it maps log_msg to printf, but no, log_msg isn't a function, but a pointer that points to a function printf.
Using a function pointer has the advantage that the log_msg can be switched at runtime. For example, you could provide a switch in the interface that
void no_log_msg(char* msg) {}
...
if (enable_debug) {
log_msg = printf;
} else {
log_msg = no_log_msg;
}
then, without changing other source code, all logging can be inhibited.
(BTW, the sample code is incorrect because the signature of printf is int printf(const char*, ...). To avoid the implicit cast, log_msg should be declared as
int (*log_msg)(const char*, ...) = printf;
)
It's a function pointer.
The type of a function pointer is R (*)(Args...), where R and Args... are replaced with the return type and arguments, if any. It is read as "a pointer to a function that takes arguments Args... and returns R."
Your code would read easier as:
// print_function is a type that is a function pointer
typedef void (*print_function)(char *msg);
// log_msg is a variable of the type print_function: it points to a function
print_function log_msg = printf; // point to printf
And later, it's just calling that function via a function pointer.
The top two lines are establishing a function pointer (hence the *), the function is named log_msg, and it's then set to point to printf - after which a call to log_msg ends up calling printf.
log_msg is a function pointer, in particular a "pointer to a function taking a char * and returning void". In this case it's just used as an alias for printf (but could point to any function with the same arguments and return type).
The syntax for function pointers in C can be pretty intimidating at first.