2

I am using C and looking to populate an array with pointers to various functions. I would like to use a function to pass the address of the function I want to put in the array. This is what I am trying to do with no success. The compiler is barking at my "task *ptr" deceleration in the prototype and registerTask function definition. I see a lot of examples of arrays with pointers to functions but none that first pass the address of the function through a function argument and then update the array. Any suggestions welcome.

typedef void (*task)(void);
task TaskArray[32];

// Prototypes
void taskA(void);
void taskB(void);
void registerTask(task *ptr);

// This is the problem function definition
void registerTask(task *ptr) {

    TaskArray[TaskIndex] = ptr;
    ++TaskIndex;

}

// Some example functions definitions
void taskA(void) { }   
void taskB(void) { }

int TaskIndex = 0;

main {

    registerTask(&taskA);       // place taskA pointer in array
    registerTask(&taskB);       // place taskB pointer in array

    ...later on...

    TaskIndex = value;          // Set the Task Array function Index
    (*TaskArray[TaskIndex]);    // call the function

}
1
  • I'm (really) old fashioned and still like the explicit (*function_ptr)(args); notation for calling a function via a pointer to function. But the second set of parentheses is necessary, with arguments if the function takes them (your task functions don't, of course). Your compiler should be warning you about a statement with no effect -- if it isn't, you need to turn up the warning level until it does (gcc -Wall is probably sufficient; I'd recommend gcc -Wall -Wextra, though I use even more stringent options for my own code). Commented Apr 3, 2014 at 23:46

3 Answers 3

4

task is a function pointer. Therefore, registerTask doesn't need to take a task *ptr parameter (which would be a function pointer pointer), just a task ptr.

Also, your syntax for calling the function is incorrect; you need the open and close parenthesis, just as if you were calling a regular ol' function.

Finally, you don't need the ampersand in front of the function names whose address you're taking - the function name is sufficient. And, you don't need to dereference the function pointer when calling it.

typedef void (*task)(void);
task TaskArray[32];

// Prototypes
void taskA(void);
void taskB(void);
void registerTask(task taskPtr);

void registerTask(task taskPtr) {

    TaskArray[TaskIndex] = taskPtr;
    ++TaskIndex;

}

// Some example functions definitions
void taskA(void) { }   
void taskB(void) { }

int TaskIndex = 0;

main {

    registerTask(taskA);       // place taskA pointer in array
    registerTask(taskB);       // place taskB pointer in array

    //...later on...

    TaskIndex = value;          // Set the Task Array function Index
    TaskArray[TaskIndex]();     // call the function

}
Sign up to request clarification or add additional context in comments.

Comments

1

I have made a few changes so the code should compile and mostly work. The changes are:

1) move the scope of TaskIndex so it can be seen by registerTask().
2) remove a lot of extra indirection
3) fixed the function pointer call

typedef void (*task)(void);
task TaskArray[32];

// Prototypes
void taskA(void);
void taskB(void);

int TaskIndex = 0;

// This is the problem function definition
void registerTask(task ptr) {
    TaskArray[TaskIndex++] = ptr;
}

// Some example functions definitions
void taskA(void) { }   
void taskB(void) { }

int
main (void)
{

    registerTask(taskA);       // place taskA pointer in array
    registerTask(taskB);       // place taskB pointer in array

    ...later on...

    TaskIndex = value;          // Set the Task Array function Index
    TaskArray[TaskIndex]();    // call the function

}

2 Comments

FYI: You still have an extra * in the registerTask prototype.
@JonathonReinhart: Thanks. Fixed by deleting the prototype.
0

IMHO things are a lot simpler if you don't use pointer typedefs. And if you use some sort of naming convention so that types are different to instances of that type. For example:

typedef void TASK(void);

// Prototypes
TASK taskA, taskB;

TASK *TaskArray[32];
int NumTasks = 0;

void registerTask(TASK *ptr)
{
    TaskArray[NumTasks++] = ptr;
}

// Some example functions definitions
void taskA(void) { }   
void taskB(void) { }

main {
    registerTask(&taskA);       // place taskA pointer in array
    registerTask(&taskB);       // place taskB pointer in array

// call the function
    TaskArray[0]();
}

1 Comment

Just tested it and it works fine. Thanks a bunch...Steve Mansfield

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.