Why function pointer?

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I just want to understand when function pointer become important to use 

 

The first question that come to mind is why would we use pointers to call a function when we can simply call a function by its name

 

#include<stdio.h>

void fun ()
{
	printf ("something \n");
}

int main ()
{
	fun (); 
}

 

function pointer 

 

#include<stdio.h>

void fun ()
{
	printf ("something \n");
}

int main ()
{
	 void (*ptr)(void) = &fun;
	 (*ptr)();
}

 

This topic has a solution.
Last Edited: Tue. Feb 18, 2020 - 12:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Common uses are in State Machines and menus.

 

The advantage of a using a pointer is that it can be set & changed at runtime.

 

For example, say you have a display and 4 buttons.

 

What each button does depends on which menu is currently displayed.

 

So you could use hard-coded function names:

switch( menu )
{
    case MENU_1: do_menu_1_stuff(); break
    case MENU_2: do_menu_2_stuff(); break
    case MENU_3: do_menu_3_stuff(); break
}

But it can be easier to have a lookup table of function pointers; eg,

 (*button_action[ menu ])();

 

EDIT

 

Another common use is in specifying a so-called callback function to some 3rd-party library.

 

Here, you are telling the library, "this is the function that I want you to call when X happens".

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Feb 18, 2020 - 11:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Function pointers are frequently used in callbacks. ‘Do this, then call this function when you’re finished’

Function pointers is a fundamental programming concept. With the questions you’ve been asking lately, maybe you want to find online courses in computer science subjects to give you a grounding. There’s also books and online content to assist.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
maybe you want to find online courses in computer science subjects to give you a grounding. There’s also books and online content to assist.

Indeed.

 

If only someone had collected together a list of such learning & reference materials - oh, wait ...

 

http://blog.antronics.co.uk/2011...

 

frown

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

A classic use of function pointer callbacks are in the FILE structure that avr-gcc uses to connect some drivers (UART/LCD/whatever) to system functions like printf()/puts()/etc

 

When the C library is written the authors can't possibly know what the output device should be - you might want printf() to come out on an LCD or you might want it to go via a UART link to a PC terminal or perhaps something completely different. So the "destination" is left undefined but printf() always prints indirectly by a "file write" field in a FILE strtucture and you, the programmer, can set up such a file structure with links to your own lcd_putchar() or uart_putchar() or whatever. Then at run time the pointers to your functions are set as the destination for the as yet undefined "stdout" channel and the core of printf() calls through the .write() entry in the structure which, if you have given a function pointer to an lcd_putchar() means the output appears on your LCD or, if you provided a function pointer to uart_putchar() it goes up a serial link to your PC (or similar) instead.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

clawson wrote:
which, if you have given a function pointer to an lcd_putchar() means the output appears on your LCD or, if you provided a function pointer to uart_putchar() it goes up a serial link to your PC (or similar) instead.

@sky33: and, because these are set at runtime (rather than hard-coded names in your 'C' source)  it means that you could easily switch between the various output devices, and enable/disable them - all at runtime and without having to rebuild the code.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yup you could do something like this:

FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
FILE lcd_str = FDEV_SETUP_STREAM(lcd_putchar, NULL, _FDEV_SETUP_WRITE);

int main(void) {
    stdout = &uart_str;
    printf("Hello to the PC connected to UART\n");
    stdout = &lcd_str;
    printf("and hello on the LCD too");
}

The destination that printf() is using is being changed "on the fly" here. First it is directed through function pointers to a routine that outputs the characters to the UART and then after just one line (stdout = &lcd_str) it now switches to using a different funciton pointer so the very same print() function now starts to send the characters to an LCD display instead.

 

Do be warned though that if the function pointers themselves are held in RAM variables then this can be a dangerous strategy. It's all too easy for bugs in computer software to inadvertently write to the wrong place in memory and if the place that is written is the location of a function pointer that actually affects the path of execution for the CPU then over-writing such a thing can have very dire consequences - like program flow going to completely the wrong place. This is why a standards organisation who recommend "safe use of C/C++" (that is "MISRA") forbid programs to use function pointers that are, themselves located in RAM. So be warned that while it's a powerful technique it's also a potentially dangerous one so is best avoided in safety critical designs like automotive or medical devices.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

sky33 wrote:
why would we use pointers to call a function when we can simply call a function by its name

Summary: using a pointer lets you call a function without having to know its name at compile time!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Sometimes, you'll find yourself with a big case statement based on some variable. Often simpler to just store what function should be called in the variable and skip the case statement.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
This is why a standards organisation who recommend "safe use of C/C++" (that is "MISRA") forbid programs to use function pointers that are, themselves located in RAM.

 

So, just declare the function pointers const so they're stored in the flash. Oh, wait... :D

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

barnacle wrote:
So, just declare the function pointers const so they're stored in the flash.
Note that declaring them const does not necessarily put them in flash.

Iluvatar is the better part of Valar.