You don't have to accept a large memory footprint from passing parameters in and out of functions. The key is to pass the parameters by reference, and to use the const
keyword to ensure that inputs are not modified. A well-known example is:
int strcpy(char *destination, const char *source);
in which only the pointers to the source and destination character buffers are passed in, not a copy of the buffers, but the const
keyword prevents strcpy() from modifying the content of the source buffer.
If you have so many parameters that passing each individually is impractical then by all means pass pointers to structs into your function instead, again, using the const
keyword to guarantee that inputs are not modified:
int myFunc(struct myFuncOut *outputs, const struct myFuncIn *inputs);
Because the struct is passed by reference, myFunc() will operate on the same memory that the calling function uses (but it will not be able to write to the memory pointed to by inputs
thanks to the const
keyword), so the memory overhead of passing it to the function is only that of the pointer, which on a typical embedded system is four bytes, and there is no copying overhead.
As for your second implied problem, that the outputs from one function need to be passed as inputs to another function, but the parameter lists are not identical, there might not be much that you can do other than copy from one struct to another. If you are lucky you might be able to do something like this:
struct myFunc1Out
{
int common1;
int common2;
int common3;
};
struct myFunc2In
{
int common1;
int common2;
int common3;
int special1;
int special2;
}
struct myFunc2In data;
myFunc1((struct myFunc1Out *)(*data), *inputs);
data.special1 = 1;
data.special2 = 2;
myFunc2(*outputs, *data);
Do you see what's happening here? The first part of struct myFunc2In is the same as struct myFunc1Out, so you can just cast the former to the latter and the extra fields will be ignored. You can think of it as a (very) poor man's polymorphism.
Another, perhaps less obscure, way would be to pass a struct myFunc1Out to the second function along with a second struct for the additional parameters. The additional memory cost is one pointer. Perhaps you can organise your data into logical groups, each represented by a struct, such that there are not too many structs yet no struct contains fields that are not always required wherever the rest of that struct is used?
By the way, one of your comments seemed to imply that you expect that a definition of a struct has a memory overhead in the executable. This is not true. Memory is used only when an instance of the struct is allocated.