is there any difference between this two syntaxes?
void fun( void (*funptr)() )
{
funptr(); // calls the function
}
void fun( void funptr() )
{
funptr(); // calls the function
}
i'd always been using the first form, but i've just seen the second one and it seems it behaves exactly the same, while the syntax is clearer.
There is no difference. In both cases, funptr has type void (*)(), a function pointer type.
C99 standard, section 6.7.5.3, paragraph 8:
A declaration of a parameter as ‘‘function returning type’’ shall be
adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1.
There is no difference, fundamentally, in either form. For both you have a function that takes a function pointer as its argument. The function pointer must point to a function with this prototype: void foo(void);.
Below is an example of use:
void fun1(void (*funptr)(void))
{
funptr(); // calls the function
}
void fun2(void funptr(void))
{
funptr(); // calls the function
}
void foo(void)
{
}
int main(void)
{
void (*pFun)(void) = foo;
fun1(pFun);
fun2(pFun);
return 0;
}
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.
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.”
I want to acquire address of a needed function in function Check_Commands, put it in pointer fptr, and then call it. But, when trying to compile this code, I get following message:
"Error[Pe137]: expression must be a modifiable lvalue"
am I missing something?
void main(void)
{
...
void(*fptr)(CmdDataType);
Check_Commands(&fptr);
(*fptr)(&CmdData);
}
void Check_Commands(void (**ptrfuncptr)(CmdDataType))
{
...
**ptrfuncptr=&DispFirmware;
...
}
void DispFirmware(CmdDataType *CmdData_ptr)
{
...
}
This:
**ptrfuncptr=&DispFirmware;
should just be
*ptrfuncptr = DispFirmware;
Also there's no need to dereference a function pointer when calling, the name of a function can be thought of as a pointer to it so an ordinary call works just like that through a pointer.
There were a couple issues with your code. Here's the fixed version:
void main(void)
{
CmdDataType CmdData;
void (*fptr)(CmdDataType *);
Check_Commands(&fptr);
(*fptr)(&CmdData);
}
void Check_Commands(void (**ptrfuncptr)(CmdDataType *))
{
*ptrfuncptr=&DispFirmware;
}
void DispFirmware(CmdDataType *CmdData_ptr) { }
fptr is a pointer to a function which takes a CmdDataType pointer as a parameter, so that needed to be fixed.
And in the function Check_Commands the function pointer needs to be dereferenced only once.
Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().
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.