GMoney
GMoney

Reputation: 159

Returning a function pointer from another function

I'm trying to write a function which will then pass on which test to run:

static uint8_t (*GetTest(uint8_t test_type))(void)
{
   switch(test_type) {
      case 0:
          return &test_a;

      case 1:
          return etc etc...
   }
}

static void test_a(void)
{
   ;
}

However, I get a warning from my compiler saying that the return value type does not match the function type. I believe that this is due to the static declarations of the function, but I am unsure of how to include them.

Upvotes: 1

Views: 131

Answers (3)

pmg
pmg

Reputation: 108968

It appears you are looking for something like this:

#include <stdio.h>
#include <stdlib.h>

typedef int (*fx_p)(int, int);

int testadd(int a, int b) { return a+b; }
int testsub(int a, int b) { return a-b; }
int testmul(int a, int b) { return a*b; }
int testdiv(int a, int b) { return a/b; }

fx_p getfx(int n) {
    switch (n) {
        default: return testadd;
        case 4: case 5: case 6: return testsub;
        case 7: case 8: return testmul;
        case 9: return testdiv;
    }
}

int main(void) {
    // missing srand on purpose
    for (int k = 0; k < 20; k++) printf("%d\n", getfx(rand() % 10)(42, 10));
    return 0;
}

You can see it running on ideone: https://ideone.com/U3it8W

Upvotes: 2

vgru
vgru

Reputation: 51204

To add to @Jabberwocky's answer, it would probably be simpler for you to create a typedef, i.e.:

// this is a function with no parameters and no return value
typedef void(*TestFn)(void);

so that it's easier to see what the GetTest function returns, and what it accepts as parameters:

// this is a function which accepts one uint8_t parameter,
// and returns a function with `TestFn` signature
static TestFn GetTest(uint8_t test_type)
{
    switch (test_type)
    {
        case 0: return &test_a;
        case 1: ...
    }
}

Upvotes: 4

Jabberwocky
Jabberwocky

Reputation: 50778

You need to make up your mind about the return type of your function.

You want either this:

#include <stdint.h>

static uint8_t test_a(void)
{
  return 1;  // you need to return something
}

static uint8_t(*GetTest(uint8_t test_type))(void)
{
  switch (test_type) {
  case 0:
    return &test_a;

//  case 1:
   // return etc etc...
  }
}

or this:

#include <stdint.h>

static void test_a(void)
{

}

static void(*GetTest(uint8_t test_type))(void)
{
  switch (test_type) {
  case 0:
    return &test_a;

//  case 1:
   // return etc etc...
  }
}

Both versions above compile without warnings.

Upvotes: 4

Related Questions