Comments requested on tutorial for function pointers

As we seem to be getting lots of questions about function pointers I wrote a tutorial about them:

Any helpful comments would be appreciated, if you think I haven't made things clear (or, made an error!).

The above example declares a type (GeneralArithmeticFunction) which is a pointer to a function which takes two int arguments, and returns void.

The above example declares a type (GeneralArithmeticFunction) which is a pointer to a function which takes two int arguments, and returns void int.

This is just my coding sytle but I always put braces after an if

i.e this code is hard to read in the first place

if (action == 0)
doAction0 ();
else if (action == 1)
doAction1 ();
else if (action == 2)
doAction2 ();
else if (action == 3)
doAction3 ();
else if (action == 4)
doAction4 ();

I think its far clearer and less prone to future errors if the code is written like this

  if (action == 0)
  {
    doAction0 ();
  }
  else 
  {
    if (action == 1)
    {
      doAction1 ();
    }
    else 
    {
      if (action == 2)
      {
        doAction2 ();
      }
      else
      {
        if (action == 3)
        {
          doAction3 ();
        }
        else
        if (action == 4)
        {
          doAction4 ();
        }
      }
    }
  }

i.e indented and clear hierarchy of braces :wink:

I'd also suggest at the end with your array example (which is basically the solution to the first bit of code, that rather than the for loop you do something like this

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

int action = 3;   // 3 is an example


    doActiontionsArray [action] ();
  }  // end of setup

Otherwise looks good. 8)

Just shows how you can read something 10 times and still miss errors. Thanks. Corrected now.

rogerClark:
I think its far clearer and less prone to future errors if the code is written like this …

I don’t know about that. Taking 30 lines to express what can be expressed in 10 isn’t necessarily clearer in my book.

Anyway, each to his own style, eh? :wink:

I’d also suggest at the end with your array example (which is basically the solution to the first bit of code, that rather than the for loop you do something like this …

Agreed. That “solves” the original problem. I’ve changed that.

I don't know about that. Taking 30 lines to express what can be expressed in 10 isn't necessarily clearer in my book.

Not sure the 30 lines instead of 10 is an issue, as it would compile to the same binary.

However, its your site and your coding style that matters.

I noticed all those questions about function pointers. You did a great job. I hope you get paid somehow ? I learned a lot from your pages, and I still do
Function pointer can be confusing very easily and I noticed a few things.

O no, a difficult word: idiosyncracy ? ? ?

I don't understand where the 'template' comes from.

The introduction can have a little more explanation. Just saying that they are variables can be overlooked, but that is the most important part. Something like: "Wouldn't it be nice if a pointer to a function was just like a variable that could be passed on and changed. Well it can. You can runtime decide to which function it point, and you can call that pointer so the function (that is pointed to) will be executed".

Once you explained that, you could mention that those pointers can be placed into a data packaged like a 'struct' or a 'Class'. Transmitting the data to another Arduino is no use, since it points to a location in flash memory that is only meaningful within that code.

Is there an alternative to 'typedef'. The 'typedef' for struct is no longer needed, and now you bring the good old 'typedef' back.

The name 'foo' is okay for software engineers, but can be confusing for new users. Perhaps it can be changed into a real name.

I don't want to deprive you from your sleep, but what about function pointers to functions with variable number of arguments ?

Since an array of function pointers are constants, can they be 'const' (I think yes) or even PROGMEM (I think no).

Peter_n:
I don't understand where the 'template' comes from.

It's not needed now, I just removed it to avoid confusion.

Is there an alternative to 'typedef'. The 'typedef' for struct is no longer needed, and now you bring the good old 'typedef' back.

It's not a struct. If you remove "typedef" it won't compile. In this case we are defining a type, used later for the variable.

The name 'foo' is okay for software engineers, but can be confusing for new users. Perhaps it can be changed into a real name.

It has a purpose, to indicate that "foo" is not an important word, but I agree it might look weird. I changed it to "func". Even then people might thing that "func" is some sort of keyword.

The introduction can have a little more explanation. Just saying that they are variables can be overlooked, but that is the most important part. Something like: "Wouldn't it be nice if a pointer to a function was just like a variable that could be passed on and changed. Well it can. You can runtime decide to which function it point, and you can call that pointer so the function (that is pointed to) will be executed".

Modified the introduction a bit. It's a fine line between too much detail and not enough.

I don't want to deprive you from your sleep, but what about function pointers to functions with variable number of arguments ?

The concept would be the same as calling function in general with variable numbers of arguments. I don't know that I want to complicate it that much.

Since an array of function pointers are constants, can they be 'const' (I think yes) or even PROGMEM (I think no).

They array could be const, although conceivably you might want to alter entries in the array. eg. make item 1 point to another function later on. As for PROGMEM, you can probably do that, but again, too much complexity for something aimed at beginners.

I agree.

You keep the idio-something word ? Yerch !

Nick, thanks for the time you put into this stuff.
You are just like the Energizer bunny, you keep on going, and going . . .

Peter_n:
Since an array of function pointers are constants, can they be 'const' (I think yes) or even PROGMEM (I think no).

Modified the page to illustrate holding the array in PROGMEM.

Peter_n:
I agree.

You keep the idio-something word ? Yerch !

You have a problem with “idiosyncracy”? It’s a perfectly good word. :slight_smile:

English is not my native language, and that idio-something word is one of the weirdest words I have seen. So yes, I think I have a problem with it. The preferred spelling is with a ‘s’ ?

Oops, looks like I misspelt it. And it is funny a non-native English speaker spotted it. :slight_smile:

Fixed now.

You discuss using functions with no arguments and then immediately show how to define them using arguments. I would first complete the discussion of using the no-argument function pointer so they see the transition in a one-to-one sense. That is, complete your discussion of using a no-argument function pointer.
Having finished that discussion and example, I would then posed the straw question: "But what if the function needs arguments and should return a value?" At that point you introduce the syntax for using function arguments and return value as an extension of what they have already seen demonstrated. I think it is less of a stretch if they complete one idea first before adding the "complexity" of the second.

Good point, and this is why I appreciate the feedback.

I moved things around to make this clearer. (I must admit I had doubts when I was writing it that way).

Just started looking into pointers, just wanted to drop in and say thank you very much for this tutorial! :smiley:

Peter_n:
The name 'foo' is okay for software engineers, but can be confusing for new users. Perhaps it can be changed into a real name.

"foo" does have a rather specific meaning:

They have been used to name entities such as variables, functions, and commands whose purpose is unimportant and serve only to demonstrate a concept.

(My emphasis)

The purpose of using foo was to make it clear that this word itself was not important, but was just a placeholder for the actual variable name, which you are free to choose.

I have changed it now, but I am interested whether other people think "foo" or something else (eg. "func" or "funcVariable") is better in this context.

And also as a new user, FUBAR is how a lot of my projects turn out.... :stuck_out_tongue: