Newbie struggling with function pointers

L

larkmore

Ok, I have some functions:

void foo1(void){
//do some stuff
}
void foo2(void){
//do some stuff
}
void foo3(void){
//do some stuff
}
void foo4(void){
//do some stuff
}

And I have an array of what I _hope_ are pointers to functions (if they
aren't, I want them to be):

void *fct_ptrs[4] = {&foo1, &foo2, &foo3, &foo4};

My question is, what would the syntax be for my program to call the
function pointed to by an element in the array (e.g. I want to execute
fct_ptr[2])? Simple and easy I'm sure, but I am having a world of hurt
trying to decipher all the tutorials on function pointers I've come
across. The concept is easy. The syntax, not so clear... Thanks in
advance for any help!
-Will
 
O

osmium

Ok, I have some functions:

void foo1(void){
//do some stuff
}
void foo2(void){
//do some stuff
}
void foo3(void){
//do some stuff
}
void foo4(void){
//do some stuff
}

And I have an array of what I _hope_ are pointers to functions (if they
aren't, I want them to be):

void *fct_ptrs[4] = {&foo1, &foo2, &foo3, &foo4};

My question is, what would the syntax be for my program to call the
function pointed to by an element in the array (e.g. I want to execute
fct_ptr[2])? Simple and easy I'm sure, but I am having a world of hurt
trying to decipher all the tutorials on function pointers I've come
across. The concept is easy. The syntax, not so clear... Thanks in
advance for any help!

This is a good place to use a typedef.

This works.

#include <stdio.h>

void f(int n)
{
printf("%d\n", n);
}
//-----------------
void g(int w)
{
printf("%d\n", 2*w);
}
//======================
int main()
{
typedef void(*FP)(int); // FP is a *type*
FP a[] = {f, g};
a[0](1024);
a[1](1024);
getchar();
}
 
R

Roger Leigh

void foo1(void){
//do some stuff
}
And I have an array of what I _hope_ are pointers to functions (if they
aren't, I want them to be):

void *fct_ptrs[4] = {&foo1, &foo2, &foo3, &foo4};

That's incorrect. Let's start with something simpler:

How do we declare and use a pointer for the above function?

The type for a pointer to a function with no arguments, and returning
void would be

void (*)(void)

and we could use it like this:

void (*ptr)(void); // a function pointer called ptr
ptr = foo1; // ptr points to foo1()
(*ptr)(); // call the pointed-to function
// or, better
ptr();

When defining an array of function pointers, it will be clearer to use
a typedef:

typedef void (*my_type)(void);
my_type func_array[4];
func_array[0] = foo1;
(*func_array[0])(); // or
func_array[0]();

Without the typedef, this would be rather ugly:
void (*func_array[4])(void)
(use typedefs, which are much clearer!)


Regards,
Roger
 
P

pete

Ok, I have some functions:

void foo1(void){
//do some stuff
}
void foo2(void){
//do some stuff
}
void foo3(void){
//do some stuff
}
void foo4(void){
//do some stuff
}

And I have an array of what I _hope_ are pointers to functions (if they
aren't, I want them to be):

void *fct_ptrs[4] = {&foo1, &foo2, &foo3, &foo4};

My question is, what would the syntax be for my program to call the
function pointed to by an element in the array (e.g. I want to execute
fct_ptr[2])?
Simple and easy I'm sure, but I am having a world of hurt
trying to decipher all the tutorials on function pointers I've come
across. The concept is easy. The syntax, not so clear... Thanks in
advance for any help!

/* BEGIN new.c */

#include <stdio.h>

void foo1(void);
void foo2(void);
void foo3(void);
void foo4(void);

int main(void)
{
size_t n;
void (*fct_ptrs[])(void) = {&foo1, &foo2, &foo3, &foo4};

for (n = 0; n != sizeof fct_ptrs / sizeof *fct_ptrs; ++n) {
fct_ptrs[n]();
}
return 0;
}

void foo1(void)
{
puts("1");
}
void foo2(void)
{
puts("2");
}
void foo3(void)
{
puts("3");
}
void foo4(void)
{
puts("4");
}

/* END new.c */
 
M

Martin Ambuhl

Ok, I have some functions:

void foo1(void){
//do some stuff
}
void foo2(void){
//do some stuff
}
void foo3(void){
//do some stuff
}
void foo4(void){
//do some stuff
}

And I have an array of what I _hope_ are pointers to functions (if they
aren't, I want them to be):

They're not. fct_ptrs is an array of pointers to void.
void *fct_ptrs[4] = {&foo1, &foo2, &foo3, &foo4};
My question is, what would the syntax be for my program to call the
function pointed to by an element in the array (e.g. I want to execute
fct_ptr[2])?

#include <stdio.h>

void foo1(void)
{
printf("%s\n", __func__);
}
void foo2(void)
{
printf("%s\n", __func__);
}
void foo3(void)
{
printf("%s\n", __func__);
}
void foo4(void)
{
printf("%s\n", __func__);
}

int main(void)
{
void (*fct_ptr[4]) (void) = {
&foo1, &foo2, &foo3, &foo4};
int i;
printf("[output]\n");
for (i = 0; i < 4; i++)
fct_ptr ();
return 0;
}

[output]
foo1
foo2
foo3
foo4
 
W

Walter Roberson

int main(void)
{
void (*fct_ptr[4]) (void) = {
&foo1, &foo2, &foo3, &foo4};

The & are permitted but not required in that initializer.
A function designator by itself is treated as the pointer to
the function.

In some quick checks, I do not easily find the relevant
section of C89, but it becomes clear when one examines the examples
of passing one function to another.
 
P

pete

Walter said:
int main(void)
{
void (*fct_ptr[4]) (void) = {
&foo1, &foo2, &foo3, &foo4};

The & are permitted but not required in that initializer.
A function designator by itself is treated as the pointer to
the function.

In some quick checks, I do not easily find the relevant
section of C89, but it becomes clear when one examines the examples
of passing one function to another.

C89 last public draft

3.2.2 Other operands
3.2.2.1 Lvalues and function designators

A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator or the unary
& operator, a function designator with type
``function returning type''
is converted to an expression that has type
``pointer to function returning type .''
 
L

larkmore

Ok, I've tried a few things and found the following. If I declare a a
typedef as follows:

typedef void ( *fn_t )( void );

and I declare my array to be:

fn_t fct_ptrs[4] = {foo1, foo2, foo3, foo4};

and I call it using a _CONSTANT_ (!!!!!) value for n in:

(fct_ptrs[n])();

Then it will work fine. However I left out a few details which will be
important and which also break things. First off, I am using GCC for
the Atmel Atmega128 microcontroller. Which means my pointer array
resides in flash memory and really looks like the following:
fn_t fct_ptrs[4] PROGMEM = {foo1, foo2, foo3, foo4};

Also, I can't have n be a constant (sort of defeats the whole
excercise). And when n is a variable, I always seem to read from the
wrong locations in memory. even when I simply assign n to the value I
had used as a constant previously. Anyone out there have experience
with this particular flavor of C syntax and could help? Thanks in
advance.!
-Will
 
O

Old Wolf

typedef void ( *fn_t )( void );

and I declare my array to be:

fn_t fct_ptrs[4] = {foo1, foo2, foo3, foo4};

and I call it using a _CONSTANT_ (!!!!!) value for n in:

(fct_ptrs[n])();

Then it will work fine. However I left out a few details which will be
important and which also break things. First off, I am using GCC for
the Atmel Atmega128 microcontroller. Which means my pointer array
resides in flash memory and really looks like the following:
fn_t fct_ptrs[4] PROGMEM = {foo1, foo2, foo3, foo4};

And when n is a variable, I always seem to read from the
wrong locations in memory.

Possibly your compiler is not initializing static data correctly
(common in embedded environments), you could try printf'ing
the values of fct_ptrs[n] (using a variable, and checking your
compiler didn't optimise it out) and printf'ing &foo1, &foo2 etc.,
and compare the results.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top