I have a question regarding C, would appreciate those who are willing to share their knowledge.
While I was reading a code, I got stumbbled in a struct that its member is called in a way that I have never seen before.
The code basically is below :
Code to call the struct member
struct struct_name gzw;
gzw.cb = otherfunct;
where the struct is defined below
struct struct_name {
int bela;
unsigned int packet;
int (*cb)(struct struct_name *fd, unsigned int packet2);
};
I kinda confused, because as I know, the cb member should be a pointer, with two parameter isn't it? howcome struct_name can call "cb" , and not (*cb with 2 parameters) ?
Thank you for your kindness response
cb is a function pointer. You can assign it to point at any function whose prototype (i.e. argument number, types and return type) matches that of the function-pointer type.
You can then call that function via the function pointer, as:
gzw.cb(arg1, arg2);
the CB member is a function pointer that takes two parameters and returns and int. The call you are confused about is assigning a pointer value and therefore does not need to reference the parameters. to the call the function the parameters would be used gzw.cb(p1,p2).
This is a function pointer. Basically, you assign a function to the struct like you would assign any other value.
Yes, cb is a function pointer that takes two arguments and returns an int.
It is not correct to say "struct_name calls cb" Instead, the structure contains a function pointer which you can call with gzw.cb(arg1, arg2);.
yes you are right. the member variable cb is a function pointer variable, taking a struct struct_name* and an integer as input and returns an int.
To call the function you have to do something like this:
int ret = gzw.cb(&gzw, 10);
Related
First of all I am not a C expert but I thought I'd be able to break down C code. I am currently reading some open source repo and have no idea what the following statement within some struct in a header file means:
struct some_struct{
...
/* Callback when non-reply message comes in (inside db transaction) */
void (*billboardcb)(void *channel, bool perm, const char *happenings);
...
}
I thought functions cannot be declared like methods within structs. But if this is a variable (called billboardcb) why are there all these paremeters? I did not find a macro called billboardcb in this code base.
A function pointer is a pointer that stores an address to a function. Function pointers can live inside structs just like any other pointer. The (void *channel, bool perm, const char *happenings) parameters listed after void (*billboardcb) are the function's parameters. The void preceding the (*billboardcb) pointer indicates that the function returns nothing.
If you search for where the some_struct struct is instantiated, you'll likely find the actual function assigned to this pointer. The function assigned to the pointer will be declared like any other function, with its address then stored in the struct by assigning the function's memory address to the struct's pointer.
It's a pointer to function, the function pointer is called billboardcb. The pointer can only point to a function with the 3 parameters that are:
1) void*
2) bool
3) const char *
The pointer can be assigned by just giving it an address of another function with compatible format.
I am trying to understand what this means, the code I am looking at has
in .h
typedef void (*MCB)();
static MCB m_process;
in .C
MCB Modes::m_process = NULL;
And sometimes when I do
m_process();
I get segmentations fault, it's probably because the memory was freed, how can I debug when it gets freed?
It defines a pointer-to-function type. The functions return void, and the argument list is unspecified because the question is (currently, but possibly erroneously) tagged C; if it were tagged C++, then the function would take no arguments at all. To make it a function that takes no arguments (in C), you'd use:
typedef void (*MCB)(void);
This is one of the areas where there is a significant difference between C, which does not - yet - require all functions to be prototyped before being defined or used, and C++, which does.
It introduces a function pointer type, pointing to a function returning nothing (void), not taking any parameters and naming the new type MCB.
The typedef defines MCB as the type of a pointer to a function that takes no arguments, and returns void.
Note that MCB Modes::m_process = NULL; is C++, not C. Also, in C, the typedef should really be typedef void (*MCB)(void);.
I'm not sure what you mean by "the memory was freed". You have a static pointer to a function; a function cannot be freed. At most, your pointer has been reset somewhere. Just debug with a memory watch on m_process.
Let's take an example
typedef void (*pt2fn)(int);
Here, we are defining a type pt2fn. Variables of this type point to functions, that take an integer as argument and does not return any value.
pt2fn kk;
Here, kk is a variable of type pt2fn, which can point to any function that takes in an integer as input and does not return any value.
Reference:https://cs.nyu.edu/courses/spring12/CSCI-GA.3033-014/Assignment1/function_pointers.html
It's a function pointer. You get a SEGMENTATION FAULT because you are trying to make a call to a function which address is invalid (NULL).
According to your specific sample, the function should return no value (void) and should receive no parameters ().
This should work:
void a()
{
printf("Hello!");
}
int main(int arcg, char** argv)
{
m_process = a;
m_process(); /* indirect call to "a" function, */
// Hello!
}
Function pointers are commonly used for some form of event handling in C. It's not its only use though...
While I went through some code, I found this declaration.
typedef int (*tMeshTable)(tOutPar *);
What is its intended purpose?
tMeshtable typedef'd to be a pointer to a function taking an tOutPar pointer and returning an int.
It's easier to say tMeshTable than that whole thing every time.
So when you want to pass it around to a function, for instance:
void functionThatCallsFunction(tMeshTable myFunction) {
tOutPar * outPar;
/* This next line calls the function that was passed into this function as a parameter */
int result = (*myFunction)(outPar);
}
it looks a lot cleaner than the raw function pointer syntax.
This page talks all about function pointers. You should give it a look: http://www.newty.de/fpt/fpt.html
I need clarification for the following notation in C:
I have a struct, and within that struct I have the following field:
bool (* process_builtin)(struct esh_command *);
I am pretty confused here.. So this is a boolean field.. What exactly is process_builtin? I already have a struct esh_command defined, but I have no clue where this plays in this field. Can someone please explain the whole thing's meaning?
That's not a boolean field, that's a pointer to a function taking a struct esh_command* and returning a bool; the field is called process_builtin.
You could also write:
typedef bool (* process_builtin_t)(struct esh_command *);
in which case process_builtin_t would be a type and in which case you could write the definition of that struct member as:
process_builtin_t process_builtin;
This a pointer to function. Using cdecl (and changing bool to int) reveals:
declare process_builtin as pointer to function (pointer to struct esh_command) returning int
This link is a permalink to the entire output.
process_builtin is a function pointer. The function it points to takes a esh_command* as parameter and returns a bool.
That is a pointer to a function that takes a pointer to struct esh_command as an argument and returns a bool value.
http://www.cprogramming.com/tutorial/function-pointers.html
I'm pretty new to C, and I'm having a really hard time reading this line of code and understanding it:
typedef void (*getnxtbyte_t)(void *stream);
From looking around, I now know that it is for a pointer pointing to a function. But could anyone help me clarify this even further? What is the name of this new type? What function is it pointing to? Is the parameter of the function (void* stream)?
Thanks in advance!
It is a tricky syntax to get used to.
What is the name of this new type?
The type is getnxtbyte_t. (You can read that trailing _t as "type". It's a popular convention.)
A variable of type getnxtbyte_t can hold the address of a function that takes one void * parameter and has return type void.
What function is it pointing to?
Wrong question.
That code merely defines the type. No variables are created so there's no "it" to point to anything.
If you know of a function with the correct signature, such as:
void some_func(void*) {}
You may now create a pointer to it using that typedef:
getnxtbyte_t my_function_pointer = some_func;
This typedef creates a type called getnxtbyte_t. That type is for a pointer to a function that returns void (i.e. nothing), as shown in the second word. That function takes a single parameter, which is a void *, shown by stream.
So if you had a function with a declaration like this:
void some_function(void *any_name);
Then you could use a typedef like the one in your post:
void *some_param = NULL;
typedef void (*getnxtbyte_t)(void *stream); // declare typedef
getnxtbyte_t func = some_function; // assign
func(some_param); // call
The function pointer type name is getnxtbyte_t. It's not pointing to anything now -- this is a type of pointer, not an actual pointer. It's just like saying
typedef struct foo {int x;} Foo;
you define a type Foo, but no actual instance of that type. And finally, yes, the function takes a single void* argument, and returns void.
I am also new to C, so if there are any errors please correct me.
A pointer that points to a function is formatted like so:
datatype (*POINTER_NAME)(PARAMETERS);
So that's the data type the pointed function returns, the name of the pointer and the parameters the pointed function takes.
Here's how a function pointer looks compared to a normal function declaration:
// normal function declaration
void getnxtbyte_t(void *stream);
// function pointer
void (*getnxtbyte_t)(void *stream);
typedef allows us to create our own type.
// will create a type called getnxtbyte_t
typedef void (*getnxtbyte_t)(void *stream);
At this point we have only declared a type; we are not pointing to anything. So let's create a pointer named func_ptr and point it to a function.
// func_ptr is a pointer of type getnxtbyte_t
getnxtbyte_t func_ptr = another_function;
// calling func_ptr is now the same as calling another_function
func_ptr(an_argument);
// had we not used typedef, we would type:
void (*getnxtbyte_t)(void *stream) = another_func;
getnxtbyte_t(an_argument);