Passing structure with list of structures to function - c

I have a function with prototype:
void procedureForEachWave(struct barge *Barge, struct settings *Settings, struct wave *Wave)
In another function I have a another structure called threadData, which I use to send information to functions that run on several threads, and one of the element of this structure is a list of struct wave, so the short vesion of this code goes:
struct threadData data;
data.waveList = (struct wave*) malloc(sizeof(struct wave)*nrOfWaves);
I use this in another function, where I basically first send a pointer to the structure data, and then inside this function the "procedureForEachWave" function is called in a loop like this:
procedureForEachWave(data->Barge, data->Settings, &data->waveList[i]);
This works fine. However, I also want to do an analysis where I only use one wave, meaning that the list only contains one element, and I therefore don't need to call the first function. I only want to do this:
procedureForEachWave(Barge, Settings, &data.waveList[0]);
but this does not work. Why? and how do I get it to work? To clarify, data is now declared as a variable, not a pointer, and Barge and Settings are pointers already. The waveList is declared like this:
data.waveList = (struct wave*) malloc(sizeof(struct wave));

Without knowing ANYTHING about what is going on inside of procedureForEachWave, it is difficult (if not impossible) to tell what the problem is.
However, it does look like data is being used differently between the call that works and the one that doesn't. If they are using the same data, the call should be the same (substituting 0 for i). If they are different, please provide a definition of this other data.

Consider the code fragment:
extern void wave_function(struct wave *);
struct wave value = { ... };
struct wave array[10] = { { ... } };
wave_function(&value);
wave_function(array);
wave_function(&array[5]);
The called function cannot tell from the pointer it was given whether it was passed a pointer to a single value or a pointer to an array of values. The calling function and the called function must agree on how the pointer will be used, perhaps by including the number of elements in the array as a separate argument:
extern void alt_wave_function(struct wave *, size_t);
alt_wave_function(&value, 1);
alt_wave_function(array, 10);
alt_wave_function(&array[5], 3);
Note that if the size passed with the pointer &value was larger than 1, you'd be into undefined behaviour. The other two calls are both wholly legitimate: the third one, though, effectively passes a three-row subset of the array to the function.
So, inside a function, any pointer argument can be treated as a pointer to a single value, or as the pointer to the first item in an array of values. Both are correct. Indeed, you can even write:
void wave_function(struct wave *ptr)
{
}
void wave_function(struct wave ptr[])
{
}
These are equivalent declarations (but only in the argument list). You can even include a size in the array notation, though that conveys no information to the function, unless you dress it up in C99 syntax:
void wave_function(struct wave array[static 4])
{
}
This notation means that the caller must guarantee that there are at least 4 elements in the array passed to this version of wave_function.

Related

How to retrieve function pointer from inside function in C?

How can I retrieve the function pointer that was used to call a function, from within the function itself? Here's an example of what I need to accomplish:
struct vtable {
void (*func)(void);
};
void foobar(void) {
// How can I get the address of t.func from here?
}
int main(void)
{
struct vtable t = { foobar };
t.func();
return 0;
}
In particular I would like to know if this can be done without using additional parameters in the function definition, ie. not this way:
struct vtable {
void (*func)(struct vtable t);
};
void foobar(struct vtable t) {
...
}
int main(void)
{
struct vtable t = { foobar };
t.func(t);
return 0;
}
This is impossible in portable C. It's also impossible on typical implementations.
When you have a function call
int main(void) {
…foobar(…)…
}
there is no way for foobar to know that it was called by main using C language constructs alone. Many implementations make this information available through debugging features that let you explore the call stack, which the implementation maintains under the hood so as to keep track of where return goes to. In practice this doesn't always match the calling structure in the source code due to compile-time transformations such as inlining.
When the function is determined through a function pointer variable, typical implementations do not keep track of this information at all. A typical way to compile t.func() is:
Load the function pointer t.func into a processor register r.
Push the current instruction pointer to the call stack.
Branch to the address stored in r.
There is no information in memory that links steps 1 and 3. Other things may have happened between steps 1 and 3 depending on how the optimizer handled this particular chunk of code.
If you need to know from which “object” a “method” was called, you need to pass a pointer to the object to the function that is the method. This is how object-oriented languages with actual methods work: under the hood, there is an extra “this” or “self” argument, even if the language doesn't make it explicit.
the problem that I'm trying to solve is how to get the address of the struct without altering the function's list of arguments
The only way to do that, short of doing it the correct way with parameter passing, is to have the caller store the address in a global variable. That's ugly but possible:
#include <stdio.h>
struct vtable {
void (*func)(void);
};
static struct vtable* lastcall;
#define call(x, func) do { lastcall=&(x); (x).func(); } while(0)
void foobar(void) {
printf("foobar caller: %p\n", (void*)lastcall);
}
int main(void)
{
struct vtable t = { foobar };
printf("Address of t: %p\n", &t);
call(t, func);
return 0;
}
I wouldn't recommend the above - it is better if you change the API to include the struct, then hide that part behind a macro if you must.
Discarding everything that's portability, it is of course also possible to dissect the stack and find the caller address there. This is ABI-specific though, and you might have to do it in assembler.
No, it is not possible. How should a function know by which way it is called?
Consider if you call the function without using a structure holding its pointer, like this:
foobar();
You need to invent some way to pass the requested value as a parameter.
I can give you a working answer, but it won't be a pretty one.
C is a pretty chill language when it comes to accessing memory. In fact you can access the entire program stack from any function, this means that you can access main variables from foobar.
Knowing this is as powerfull as it is usually a bad idea.
For your problem, you can search any pointer to your foobar function in a range. Simply by creating a struct vtable pointing to ARBITRARY addresses stored at the stack and then checking if the func field is the same as the address of foobar.
Usually this will yield a SIGSEGV, to avoid this you can limit the addresses used to stack valid addresses using pointer arithmetic.
Here you have a working example in "pure" c (simply play with the RANGE define). But i have to warn you again, dont use this in the real world, unless you want to flex on your hacking skills.
#include <stdio.h>
#define RANGE 100
struct vtable {
void (*func)(void);
};
void foobar(void) {
int a[1]; //We control the stack from this address!
for (int i = 0; i < RANGE; i++) { //We are basically doing a buffer overflow
if (a[i] > a && a[i] < a+RANGE) { //Ignore addresses too far to prevent SEGF
struct vtable *t = (struct vtable*)a[i];
if (t->func == foobar)
printf("[FOOBAR] Address of t is: %x\n", a[i]);
}
}
}
int main(void)
{
struct vtable t = { foobar };
printf("[MAIN] Address of t: %x\n", &t);
t.func();
return 0;
}
Have a nice day!
First of all, you cannot get the address of t if you don't pass any reference to it. This is like trying to follow a pointer back to it's pointer. Pointers in general don't work in the reverse, and this is the reason to write data structures like double linked lists, or similar. Simply you can have millions of such pointers, all pointing to this function, so there's nothing in the function address that allow you to know where the function pointer was stored.
Once said that:
In your first paragraph you say:
How can I retrieve the function pointer that was used to call a function, from within the function itself?
Well, that's preciselly what you get when you use the plain name of the function (as in main) you can then execute that function using a (probably non empty) argument list, as you do in (). You don't know where your function has been called from, but what is true, is that if your program control is inside the body of it, it must have been called from the beginning, so using the function name inside the function could be a way to get a function's pointer. But you cannot get it further and get the structure where that pointer was used... this information is not passed in to your function, you have no means to get to it. This is the same problem as when you are forced to pass an array length to a function because there's nothing in the array that allows you to get how large it is.
I have not checked thoroughly your code, as it is just a snippet of code, that needs some adjustments to evolve into fully executable code, but from my point of view it is correct and will do what you are thinking on. Just test, the computer is not going to break if you make a mistake.
Beware in your code you have passed a full struct record by value, and that will make a full copy of the struct in order to put it in the parameter stack. Probably what you want is something like:
struct vtable {
void (*func)(void); /* correct */
};
void foobar(void) {
// How can I get the address of t.func from here?
/* if you want to get the address of the function, it is
* easy, every function knows its address, is in its
* name */
void (*f)(void) = foobar; /* this pointer is the only one
* that could be used to call
* this function and be now
* executing code here. :) */
/* ... */
f(); /* this will call foobar again, but through the pointer
* f, recursively (the pointer although, is the same) */
}
int main(void)
{
struct vtable t = { foobar };
t.func();
return 0;
}
It is very common to see functions that use callbacks to be executed on behalf of the calling code. Those functions is common also to require pointers to strcutres that represent the context they are called in behalf of. So don't hesitate to pass arguments to your function (try not to pass large structures by value, as you do in your example ---well, I recognize it is not large, it has only a pointer) but anyway, that is very common. OOP implementation rests deeply on these premises.

Typecasting for functions with different arguments in c

So I have two functions that does the same thing but on different type variables.
The first function fills up an array of integers when given an int arr[] argument.
The second function fills up a linked list with integers also when given a struct as an argument.
The struct for the linked list argument looks something like this
typedef struct {node_t *head;int size;}
list_t;
Now I have implemented a table of function pointers for the two functions as such:
typedef struct{
char *name; //name of the function
void (*fill)(int arr[]); //fill up the array
} alg_t;
alg_t algs[] = {
{"func1",fill_up_arr},
{"func2",fill_up_linkedList}
};
Notice that inside the struct that holds my pointers, the fill function pointer
takes int arr[] as an argument.
I only want one pointer of a function in that struct, is there a way I can use
typecasting so that other functions such as fill_up_linkedList require argument to be of type list_t instead of int arr[]?
//This is what I want my main to look like.
//I want func.fill to be called only once thus
//dynamically perform the operations for all functions inside the table of
//functions array
int arr = malloc(sizeof(int)algs.size);
for(int i = 0; i<algs.size;i++){
alg_t func = algs[i];
func.fill(arr);
}
It seems that the problem with this code would be when the loop would try and perform the fill_up_LinkedList function as it needs a different argument.
How can I use a typecast in this situation?
Thanks
The good news
C11 §6.3.2.3 Pointers ¶8 (under the general topic §6.3 Conversions) says:
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 referenced type,
the behavior is undefined.
That means you can store any and all function pointers in a common function pointer type, for example typedef void (*GenericFunctionPointer)(void). What is crucial, though, is that you convert from that generic function pointer type back to the correct function pointer type before you invoke the function via the pointer (and that you provide the correct argument list, and that you handle the return type appropriately, though ignoring the return value, if any, is always an option).
The bad news
For two different function pointer types, each with one instance of the the function, the infrastructure needed to support this is probably more elaborate than the savings, if any. On the other hand, if you have two or more different function pointer types, and most if not all of the types have many representative functions ('many' meaning 'more than one', as in the computer engineer's counting: "zero, one, many"), then the infrastructure can pay off. One of the issues is marshalling the function arguments — how are the arguments made accessible so that the function can be called via the pointer with the correct arguments.
So, doing things this way is complex and verbose.
The stated requirement
In a comment, the OP Moi says:
I only want to put one function in the struct. My goal is to find a way to allow fillArray to allow the passing of different args.
I have major reservations about the use of an uncounted array as the argument list as shown in the question — void (*fill)(int arr[]) is shown. In my view, it should be void (*fill)(size_t n, int arr[n]), using the variable length array notation. You can omit the n in the subscript if you wish — void (*fill)(size_t n, int arr[]) — or even use void (*fill)(int arr[], size_t n), which is the more classic order for the arguments.
Putting this concern aside, if you want a single function to accept different arguments, one way to achieve that is with void * as the type, but you have to be aware of the problems — one of which is type safety. You'll also need to borrow ideas from the standard C functions qsort() and bsearch(). The argument list will include the pointer to the start of the array as a void *, the size of each element of the array, and the number of elements in the array. You may also need analogues to the comparator functions.
Internal to the single called function, though, you will probably end up with two code paths, so although you call a single function via the pointer, you end up doing the equivalent of implementing two functions. You could use an interface similar to qsort()'s so that the two functions have the same interface and different bodies, and you use two pointers in the alg_t array.
Summary
You probably can't achieve the stated requirement cleanly.
You will probably need two logically separate functions to handle the two separate interfaces, even if you smush all the code inside a single function.
Use a union:
typedef struct {
char *name; //name of the function
union {
void(*fillArray)(int arr[]); //fill up the array
void(*fillList)(YourListType list); //fill up the list
};
} alg_t;
alg_t a;
a.fillArray(...);
a.fillList(...);
Or:
typedef struct {
char *name; //name of the function
union {
void(*fillArray)(int arr[]); //fill up the array
void(*fillList)(YourListType list); //fill up the list
} functions;
} alg_t;
alg_t a;
a.functions.fillArray(...);
a.functions.fillList(...);
Since you only have 2 types, you can just use an enum and a macro
enum e_type {e_foo,e_bar};
#define do_foobar(e,...) (e)?bar(__VA_ARGS__):foo(__VA_ARGS__)
replace foo and bar with your function names
If you only have the problem with the function parameters and not with the return value, there's a trick related to incomplete type definitions. The trick consists in leaving empty the list of parameters in the pointer type declaration, as in:
typedef void (*callback_ptr)();
which is different from:
typedef void (*callback_ptr)(void);
in the first case, the compiler will not check the parameters passed to the function, as the pointer is a pointer to an incompletely defined function type, while the second explicitly says the function doesn't require parameters and will give you an error if you try to call it with them.

C: Why can you pass (to a function) a struct by value, but not an array?

Any historical or logical reasons behind it?
Explanation:
when you pass an array to a function in C you actually only pass a pointer to an array.
However, when you pass a struct, you can either pass a copy of the struct or the pointer.
//this:
int function(int array[10])
// is equivalent to this:
int function(int *array)
//and they both pass a pointer
//but this:
int function(struct tag name)
//passes a struct by value, where as this:
int function(struct tag *name)
//passes a pointer to it.
Why the difference?
In the original K&R, you could not pass structs by value. That was a syntax error. Because many compiler vendors offered it as an extension, pass-by-value eventually made its way into the standard.
Why the restriction, and why the evolution? The machines that C was developed on were tiny. Segment sizes of 64 kilobytes were common. Memory was precious, so why copy something when you could just pass the address? Duplicating a 64-byte structure on the stack was an error, probably not even what the user intended.
By the mid-1990s, that wasn't true anymore. 32-bit addressing and RAM of 4 MB or more were common. The restriction was a hinderance and led to some complexity, because without const a structure passed by reference could be modified, perhaps unwittingly.
Why not do the same with arrays? No demand. Arrays and pointers are closely related in C, as you know. The C standard library depends heavily on passing by reference, consider memset and strcpy. Whereas passing a struct by value meant just dropping the & on the call, passing an array by value would have entailed adding new syntax. A compiler vendor that offered, say, by value as C syntax would have been laughed out of the conference.
int function(int array[10]) and int function(int *array) are the same because of 6.7.5.3 Function declarators (including prototypes) (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf page 118)
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted
to ‘‘qualified pointer to type’’, where the type qualifiers (if
any) are those specified within the [ and ] of the array type
derivation. If the keyword static also appears within the [ and
] of the array type derivation, then for each call to the
function, the value of the corresponding actual argument shall
provide access to the first element of an array with at least as many
elements as specified by the size expression
.
Of course, you can pass an array by value; all you need to do is wrap it in a struct. But that only works if the array has a definite (and non-variable) size. You can include an indefinitely sized array in a struct, but the resulting type is incomplete and can only be used as the target of a pointer.
That's probably as close as we're going to get to an explanation. The vast majority of arrays passed as arguments are not of fixed size, and passing them by value would not be possible, even if it were intended, which is also unlikely.
There is a similar (but different) decay with functions; a function cannot be passed as an argument, only function pointers. Since it would be tedious to explicitly write & every time you wanted to refer to a function, the language takes care of it for you.
On the whole, questions of the form "Why is this language like this snd not like that?" can only be answered "because that's how it is".
Types are different in both function declarations -
struct tag /* and */ struct tag *
One is structure variable whereas another is pointer to structure.
You can do similar with structures -
int function(struct tag name[]) /*--> int function(struct tag *name) */
These above would be equivalent.
structs are used for declaring own kind of data types with primitive data types like int,float,long(or structs of structs) etc. they are supposed to hold a few of them e.g. struct of students will contain id,name,rollno,subjects,etc. so mostly any struct element will contain 10-20 fields at most (in logical cases), so when you pass a struct to a function, it has to copy 40-100 bytes approx. to make copy of that struct variables. where as arrays can be of huge size and are used to store same kind of information. they can be of size 10^7 in case of integers so if we implement a language to copy whole array for function calls it may have to copy (10^7)*4 bytes which is a huge amount and will impact the performance badly.and typical size of arrays is 10^4 to 10^6 which is still a lot. but if you create struct of array of int(or any other array) you can pass it to a function as a copy of that array. e.g.
#include<stdio.h>
typedef struct {
int arr[10];
}arrayStruct;
void change(arrayStruct a){
a.arr[2]=5;
}
int main(){
arrayStruct a;
for(int i=0;i<10;i++){
a.arr[i]=i;
}
printf("Before:\n");
for(int i=0;i<10;i++){
printf("%d ",a.arr[i]);
}
change(a);
printf("\nAfter:\n");
for(int i=0;i<10;i++){
printf("%d ",a.arr[i]);
}
return 0;
}
this is not done in most of the cases but few times when you need to pass arrays but don't want to alter the contents of them but also require some kind of changes to their copies and want to return that copy you can use this kind of structs of arrays and return them from functions of return type of structs e.g.
arrayStruct returnChange(arrayStruct a){
a.arr[2]=332;
return a;
}

Invoking a function calculation in C through a pointer defined in a structure, when function is written in assembly code

I have a piece of code I am trying to understand how it works. SGENT_1_calc is a signal generator function, written as assembly code elsewhere. When the calculation is invoked in C, sgen.calc(&sgen), requires its own structure address as argument. Why ?
THANKS IN ADVANCE FOR YOUR HELP !
typedef struct {
unsigned int freq;
unsigned int step_max;
unsigned int alpha;
int gain;
int offset;
int out;
void (*calc)(void *);
}SGENT_1;
#define SGENT_1_DEFAULTS { 5369,
1000,
0,
0x7fff,
0,
0,
(void (*)(void *))SGENT_1_calc} // pointer casted here ???
void SGENT_1_calc(void *); //SGENT1_calc is a signal generator function
SGENT_1 sgen = SGENT_1_DEFAULTS; // this is an instance
sgen.calc(&sgen); //don't understand how the calculation is invoked,
// why it has &sgen as an argument ???
sgen.calc is a pointer to a function accepting one argument of type void * and returning nothing. It is irrelevant how the machine code of the pointed-to function was produced. In any event, the value of sgen.calc carries no information about the variable in which that value is stored, so if sgen contains the data to be submitted to the function, then the fact that its calc member points to that function doesn't provide any way around passing (a pointer to) that struct.
Given no other information about the function pointed to by sgen.calc, a pointer to sgen is as good an argument for it as any other object pointer. There is nothing inherently special about choosing that particular argument over any other.
In fact, however, it is reasonable to suppose that the function assumes its argument to point to a data structure with a particular layout. The C code implies that type SGENT_1 is consistent with that layout. It is impossible to determine from the code presented whether the function uses the calc member of that struct, but its placement as the last member is consistent with it not doing so. In that case, it may be included in the C struct simply for organizational purposes.

Passing more parameters in C function pointers

Let's say I'm creating a chess program. I have a function
void foreachMove( void (*action)(chess_move*), chess_game* game);
which will call the function pointer action on each valid move. This is all well and good, but what if I need to pass more parameters to the action function? For example:
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
foreachMove(moveHandler, game);
}
void moveHandler(chess_move* move){
//uh oh, now I need the variables "game" and "depth" from the above function
}
Redefining the function pointer is not the optimal solution. The foreachMove function is versatile and many different places in the code reference it. It doesn't make sense for each one of those references to have to update their function to include parameters that they don't need.
How can I pass extra parameters to a function that I'm calling through a pointer?
Ah, if only C supported closures...
Antonio is right; if you need to pass extra parameters, you'll need to redefine your function pointer to accept the additional arguments. If you don't know exactly what parameters you'll need, then you have at least three choices:
Have the last argument in your prototype be a void*. This gives you flexibility of passing in anything else that you need, but it definitely isn't type-safe.
Use variadic parameters (...). Given my lack of experience with variadic parameters in C, I'm not sure if you can use this with a function pointer, but this gives even more flexibility than the first solution, albeit still with the lack of type safety.
Upgrade to C++ and use function objects.
You'd probably need to redefine the function pointer to take additional arguments.
void foreachMove( void (*action)(chess_move*, int), chess_game* game )
If you're willing to use some C++, you can use a "function object":
struct MoveHandler {
chess_game *game;
int depth;
MoveHandler(chess_game *g, int d): game(g), depth(d) {}
void operator () (chess_move*) {
// now you can use the game and the depth
}
};
and turn your foreachMove into a template:
template <typename T>
void foreachMove(T action, chess_game* game);
and you can call it like this:
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
foreachMove(MoveHandler(game, depth), game);
}
but it won't disrupt your other uses of MoveHandler.
If I'm reading this right, what I'd suggest is to make your function take a pointer to a struct as an argument. Then, your struct can have "game" and "depth" when it needs them, and just leave them set to 0 or Null when you don't need them.
What is going on in that function? Do you have a conditional that says,
if (depth > -1) //some default
{
//do something
}
Does the function always REQUIRE "game" and "depth"? Then, they should always be arguments, and that can go into your prototypes.
Are you indicating that the function only sometimes requires "game" and "depth"? Well, maybe make two functions and use each one when you need to.
But, having a structure as the argument is probably the easiest thing.
I'd suggest using an array of void*, with the last entry always void.
say you need 3 parameters you could do this:
void MoveHandler (void** DataArray)
{
// data1 is always chess_move
chess_move data1 = DataArray[0]? (*(chess_move*)DataArray[0]) : NULL;
// data2 is always float
float data1 = DataArray[1]? (*(float*)DataArray[1]) : NULL;
// data3 is always char
char data1 = DataArray[2]? (*(char*)DataArray[2]) : NULL;
//etc
}
void foreachMove( void (*action)(void**), chess_game* game);
and then
chess_move getNextMove(chess_game* game, int depth){
//for each valid move, determine how good the move is
void* data[4];
data[0] = &chess_move;
float f1;
char c1;
data[1] = &f1;
data[2] = &c1;
data[3] = NULL;
foreachMove(moveHandler, game);
}
If all the parameters are the same type then you can avoid the void* array and just send a NULL-terminated array of whatever type you need.
+1 to Antonio. You need to change your function pointer declaration to accept additional parameters.
Also, please don't start passing around void pointers or (especially) arrays of void pointers. That's just asking for trouble. If you start passing void pointers, you're going to also have to pass some kind of message to indicate what the pointer type is (or types are). This technique is rarely appropriate.
If your parameters are always the same, just add them to your function pointer arguments (or possibly pack them into a struct and use that as the argument if there are a lot of parameters). If your parameters change, then consider using multiple function pointers for the multiple call scenarios instead of passing void pointers.
If your parameters change, I would change the function pointer declaration to use the "..." technique to set up a variable number of arguments. It could save you in readability and also having to make a change for each parameter you want to pass to the function. It is definately a lot safer than passing void around.
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html
Just an FYI, about the example code in the link: some places they have “n args” and others it is “n_args” with the underscore. They should all have the underscore. I thought the syntax looked a little funny until I realized they had dropped the underscore in some places.
Use a typedef for the function pointer. See my answer for this question
Another option would be to modify the chess_move structure instead of the function prototype. The structure is presumably defined in only one place already. Add the members to the structure, and fill the structure with appropriate data before any call which uses it.

Resources