0

I'm trying to understand how to implement a two-dimension table of function pointers (to simplify a semi-complex switch/case/if construct).

The following worked - after some wrangling - as desired.

#include <stdio.h>

void AmpEn(void) {printf("AmpEn\n");}
void MovCurColumn1(void) {printf("MovCur\n");}
void AmpLevel(void) {printf("AmpLevel\n");}
void Phase(void) {printf("Phase\n");}

typedef void (*func_ptr)(void);

int main (void) {

    func_ptr table[2][2] = {{AmpEn, MovCurColumn1},{AmpLevel, Phase}};
    func_ptr *p;

    // runs all the fcns
    for (p = &table[0][0]; p < &table[0][0] + 4; p++) {
        (*p)();
    }

    // calls 0th fcn
    p = &table[0][0];
    (*p)(); p++;;
    (*p)();

    // calls 2nd fcn
    table[0][1]();

    return 0;
}

Now what I want is to pass arguments to the functions - for example, to change void Phase(void) to

void Phase(int mode) and call it via some similar construct to:

table[1][1](TRUE);

but I haven't figured out how to do this. Any help welcome.

mike65535
  • 483
  • 2
  • 10
  • 21
  • 1
    1. I’m not sure about C and this may be fine, but at least in C++ you can’t legally iterate over a two-dimensional array as if it were one-dimensional. 2. Do you want to change *all* the functions to accept the *same* parameters? – Daniel H Apr 19 '18 at 18:06
  • (and 3. `Phase` looks like it’s `table[1][1]`, not `table[0][1]`, but that’s probably just a typo) – Daniel H Apr 19 '18 at 18:08
  • @Daniel and 3. Phase looks like it’s table[1][1], not table[0][1], but that’s probably just a typo) – Yes, just a typo in my wishlist - I'll fix that – mike65535 Apr 19 '18 at 18:10
  • @Daniel "2. Do you want to change all the functions to accept the same parameters?" No. I want different sized parameter lists for each fcn. Some with 2 ints, some with void, etc. I have just now been able to get this to work if all of them are the same. So, are different parameter sizes not possible in this construct? – mike65535 Apr 19 '18 at 18:13
  • 1
    If they need to take different arguments, how would you use an array and a loop then? Why not store the pointers in a struct instead? Or use different variables altogether? – melpomene Apr 19 '18 at 18:16
  • @mel In the final code I only want the table[0][1](value); construct to work. The other versions of using the pointers were just for test. – mike65535 Apr 19 '18 at 18:21
  • 1
    @mike65535 Then what's the point of storing them in an array instead of just using their names? – Daniel H Apr 19 '18 at 18:25
  • 1
    I believe this is an XY problem. This question would benefit from showing the original "semi-complex switch/case/if construct" that needs to be simplified. – melpomene Apr 19 '18 at 18:26
  • @melpomene I never completed the original construct due its getting ugly fast - I was thinking that a navigable set of function pointers was the better way to go. I don't know for sure what you mean by "XY problem" but my main goal is an ncurses array of menu items that a user traverses using arrow keys. The row/col of the current position in the menu I intended to be the two array indices. Along the way I thought learning function pointers/jump tables would be worthwhile for this hack. ;-) – mike65535 Apr 19 '18 at 18:37
  • @mike65535 If the functions accept different parameters, then you'd still somehow need to look up what parameters to give them based on the index, so I'm not sure that would help. – Daniel H Apr 19 '18 at 18:39
  • https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – melpomene Apr 19 '18 at 18:39
  • @mike65535 An [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) is when you say "I want to do Y", but you only really want that so you can do X and it turns out Y isn't the best way to do X. – Daniel H Apr 19 '18 at 18:40
  • Yeah, thanks guys - I just looked it up - it's a bit of a pun on my current problem (navigating a set of items in a ncurses menu if you know what I mean). – mike65535 Apr 19 '18 at 18:41
  • @mike65535 At least it's not called the XYZ problem or you'd need to make a 3d UI. But how do you intend to know what arguments to pass to a function just given its coordinates, if they take different sets of arguments, without the sort of ugly `switch` logic you're trying to avoid? – Daniel H Apr 19 '18 at 19:08
  • Back to the original question, if you have a bunch of function pointers and you want to call them with potentially different arguments that you might not know until run time, this is what I call the "inverse varargs problem" and it's a fun one. These days it's most easily solved, I think, with something like libffi. – Steve Summit Apr 19 '18 at 22:22

0 Answers0