Pointers to function

Are there in Arduino pointers to function?
As they are declared and defined?
As to the function accessed through a pointer?

Ogogon

1 Like

Are there in Arduino pointers to function?
As they are declared and defined?

  1. yes
  2. exactly as for C/C++

And for anyone that hasn't seen it done recently:

// Generic arithmetic funtion
typedef int (*GeneralFunction) (const int arg1, const int arg2);

int Add (const int arg1, const int arg2)
{
 return arg1 + arg2; 
} // end of Add

int Subtract (const int arg1, const int arg2)
{
 return arg1 - arg2; 
} // end of Subtract

int Divide (const int arg1, const int arg2)
{
 return arg1 / arg2; 
} // end of Divide

int Multiply (const int arg1, const int arg2)
{
 return arg1 * arg2; 
} // end of Multiply

void setup ()
{
 // make pointers to functions, put them in local variables
  GeneralFunction fAdd = Add;
  GeneralFunction fSubtract = Subtract;
  GeneralFunction fDivide = Divide;
  GeneralFunction fMultiply = Multiply;
  
  Serial.begin (115200);
  Serial.println ();
  
  //  use the function pointers
  Serial.println (fAdd (40, 2));
  Serial.println (fSubtract (40, 2));
  Serial.println (fDivide (40, 2));
  Serial.println (fMultiply (40, 2));
}  // end of setup

void loop () {}

Output:

42
38
20
80

Function pointers are useful for generic things (eg. do to everything in an array). Also for callbacks. That is, you might want to do on an interrupt.

2 Likes

Here is an example of where you might pass the pointer to a function to another "generic" function:

int Add (const int arg1, const int arg2)
{
 return arg1 + arg2; 
} // end of Add

int Subtract (const int arg1, const int arg2)
{
 return arg1 - arg2; 
} // end of Subtract

int Divide (const int arg1, const int arg2)
{
 return arg1 / arg2; 
} // end of Divide

int Multiply (const int arg1, const int arg2)
{
 return arg1 * arg2; 
} // end of Multiply

int DoSomething (int (*f) (const int arg1, const int arg2), const int a, const int b)
{
 Serial.println (f (a, b));   // call the passed-in function
}

void setup ()
{
  Serial.begin (115200);
  Serial.println ();

  DoSomething (Add, 40, 2);
  DoSomething (Subtract, 40, 2);
  DoSomething (Divide, 40, 2);
  DoSomething (Multiply, 40, 2);
}  // end of setup

void loop () {}

Here the DoSomething function is passsed the pointer to a function which is the function which you want it to call.

(edit) Amended to change (*f) (arg1, arg2) to f (a, b) in DoSomething.

However I believe there is a bug in the IDE preprocessor. This "easier-to-read" version does not compile:

// Generic arithmetic function
typedef int (*GeneralFunction) (const int arg1, const int arg2);

int Add (const int arg1, const int arg2)
{
 return arg1 + arg2; 
} // end of Add

int Subtract (const int arg1, const int arg2)
{
 return arg1 - arg2; 
} // end of Subtract

int Divide (const int arg1, const int arg2)
{
 return arg1 / arg2; 
} // end of Divide

int Multiply (const int arg1, const int arg2)
{
 return arg1 * arg2; 
} // end of Multiply

int DoSomething (GeneralFunction f, const int arg1, const int arg2)
{
 Serial.println ((*f) (arg1, arg2));    // call the passed-in function
}

void setup ()
{
  Serial.begin (115200);
  Serial.println ();

  DoSomething (Add, 40, 2);
  DoSomething (Subtract, 40, 2);
  DoSomething (Divide, 40, 2);
  DoSomething (Multiply, 40, 2);
}  // end of setup

void loop () {}

Error message:

sketch_apr16a:-1: error: 'GeneralFunction' was not declared in this scope
sketch_apr16a:-1: error: expected primary-expression before 'const'
sketch_apr16a:-1: error: expected primary-expression before 'const'
sketch_apr16a:-1: error: initializer expression list treated as compound expression
sketch_apr16a.cpp: In function 'int DoSomething(int (*)(int, int), int, int)':
sketch_apr16a:23: error: 'int DoSomething(int (*)(int, int), int, int)' redeclared as different kind of symbol
sketch_apr16a:-1: error: previous declaration of 'int DoSomething'
sketch_apr16a.cpp: In function 'void setup()':
sketch_apr16a:33: error: 'DoSomething' cannot be used as a function
sketch_apr16a:34: error: 'DoSomething' cannot be used as a function
sketch_apr16a:35: error: 'DoSomething' cannot be used as a function
sketch_apr16a:36: error: 'DoSomething' cannot be used as a function

But GeneralFunction is declared in this scope. It worked in the earlier example (reply #2). However this code does compile under normal g++. So I have the syntax right.

1 Like

Ah well, I worked it out. It's always satisfying to do that. :wink:

If you split the code up into two files the cleaner-looking one compiles OK. Main file:

#include "functionheader.h"

int Add (const int arg1, const int arg2)
{
 return arg1 + arg2; 
} // end of Add

int Subtract (const int arg1, const int arg2)
{
 return arg1 - arg2; 
} // end of Subtract

int Divide (const int arg1, const int arg2)
{
 return arg1 / arg2; 
} // end of Divide

int Multiply (const int arg1, const int arg2)
{
 return arg1 * arg2; 
} // end of Multiply

int DoSomething (GeneralFunction f, const int a, const int b)
{
 Serial.println (f (a, b));    // call the passed-in function
}

void setup ()
{
  Serial.begin (115200);
  Serial.println ();

  // call the general "do something" routine passing down what function to do, and its arguments
  DoSomething (Add, 40, 2);
  DoSomething (Subtract, 40, 2);
  DoSomething (Divide, 40, 2);
  DoSomething (Multiply, 40, 2);
}  // end of setup

void loop () {}

Then make another tab in the IDE called functionheader.h and put this into it:

// Generic arithmetic function
typedef int (*GeneralFunction) (const int arg1, const int arg2);

(edit) Amended to change (*f) (a, b) to simply: f (a, b) in DoSomething.

1 Like

Thank you very much. I have written in both C and everything is fine success.

Ogogon.

I found this very useful. Thanks Nick