Passing a value to functions held in an array of functions

This simple sketch runs func0() and func1() as expected and prints the expected messages

void func0();   //function prototypes needed
void func1();

void (*functions[])() = {func0, func1};
const byte NUMBER_OF_FUNCTIONS = sizeof(functions) / sizeof(functions[0]);

void setup()
{
  Serial.begin(115200);
  for (int f = 0; f < NUMBER_OF_FUNCTIONS; f++)
  {
    functions[f]();
  }
}

void loop()
{
}

void func0()
{
  Serial.println(F("in func0"));
}

void func1()
{
  Serial.println(F("in func1"));
}

Can a parameter to be passed to the functions ?
This attempt

void func0(int x);   //function prototypes needed
void func1(int x);

void (*functions[])() = {func0, func1};
const byte NUMBER_OF_FUNCTIONS = sizeof(functions) / sizeof(functions[0]);

void setup()
{
  Serial.begin(115200);
  for (int f = 0; f < NUMBER_OF_FUNCTIONS; f++)
  {
    functions[f](f);
  }
}

void loop()
{
}

void func0(int x)
{
  Serial.println(F("in func0"));
  Serial.println(x);
}

void func1(int x)
{
  Serial.println(F("in func1"));
  Serial.println(x);
}

won't compile and produces the error

C:\Users\Bob2\AppData\Local\Temp\arduino_modified_sketch_291424\array_of_function_pointers.ino: In function 'void setup()':

array_of_function_pointers:12:19: error: too many arguments to function

     functions[f](f);

                   ^

exit status 1

too many arguments to function

I suspect that this is not possible because the array is an array of pointers, but is there some way to do it ?

void (*functions[])(int) = {func0, func1};

Try:

void (*functions[])(int) = {func0, func1};

Edit:
What he said.

@wildbill @gfvalvo Thanks, that works and it works with multiple parameters too.

Easy when you turn on your brain !

Now for the killer follow-up. Suppose each function has a different mix of parameters ? I can work round it by giving each function the same parameter list, providing dummy values for any not needed and ignoring them in the function, but that is very inelegant

I don't know. There must be some mumble mumble C++ thing with function overrides, but I can't see how you would call them from a loop like that. It might make more sense with a concrete example if you have one, but I think you will need @PieterP

But in that case they wouldn't belong in the same array, would they?

It might make sense to bind arguments to some function, i.e. creating a closure and eliminating some parameters by replacing them with a fixed value before adding the function to the array, but having functions with different signatures in the same array feels wrong, and cannot be type-checked at compile time.

Edit: for the sake of readability, you could use:

using my_func_t = void (*)(int); // pointer to function from int → void
my_func_t functions[] = {func0, func1};
1 Like

I don't have a concrete example, it is just something that I was experimenting with as a possible alternative to a switch/case that called functions, so no problem if it is not possible or is too complicated to make it worthwhile

I think that is the key thing and you are right, that feels wrong, rather like trying to have an array of different data types. If only you could iterate through the elements of a struct...

Thanks for all the input

Since you need to know which function you are calling to know which argument list to pass:

  switch (whichFunction)
  {
  case 0: func0(arg list for func0); break;
  case 1: func1(different arg list for func1); break;
  }

Another option is to declare the argument as a 'void *'. Then you can pass any pointer, to a single value or a whole struc t of values. Each function needs to know what kind of pointer to cast the void * to.

Another is to make all of the functions Variadic: taking a variable number of arguments. That is how printf() can take a variable number of arguments of various types. The called function has to know what types are passed and in what order.

Thanks John. The switch/case was where I started and the array of function pointers was just an interesting diversion from which I learnt something and others might too if they come across this topic

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.