0

Hello StackOverflow Community,

How do I call a function from a function pointer array based on the passed opcode?

For example when I read the opcode '0x1A' and pass it to a function pointer array I want to call some function for example 'add()'.

How can I do that without using switch/case ?

My function pointer array:

void (*execOp[4])(int opcode) = { add, sub, div, mul };

My Codebase:

const int memory[2]= {0x1A, 0x1D}; // Memory
int pc=0; //Program counter
int opcode; //Current opcode

//Functions
void fetch()
{
  opcode=memory[pc];
}  

void add()
{
  printf("add");
}


int main()
{
  //Decoding Opcodes from Memory
  for(;;)
  {
    fetch();
  }

    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
M.Hisoka
  • 1
  • 1
  • What's wrong with `switch/case`? Alternatively you can let the opcode to index the array, but it might result in an oversized array. – Eugene Sh. Dec 06 '17 at 20:29
  • Map the opcodes [0x1A, 0x1D, ...] into array indices [0, 1, ...] in a function. Store pointers to the functions in a corresponding array, and invoke the function pointer using something like (*funcptr[index])(). – jarmod Dec 06 '17 at 20:30
  • @EugeneSh. As far as I know switch/case evaluation is slower than using a function pointer array. Also another problem is to index the array because then I would have an oversized array as you have mentioned. – M.Hisoka Dec 06 '17 at 20:30
  • 2
    If you can't come up with some straight-forward mapping opcode->index, then you will have to face the trade-off. – Eugene Sh. Dec 06 '17 at 20:32
  • See https://stackoverflow.com/questions/252748/how-can-i-use-an-array-of-function-pointers. – jarmod Dec 06 '17 at 20:34
  • 2
    Do all relevant functions have the same signature (i.e. same number/type of parameters and return type)? If so, you can use a function pointer array. If not, you'll have to use a `switch` statement. – dbush Dec 06 '17 at 20:36
  • 1
    Where is your function pointer array? The notation I'd use is `(*array[index])(arg1, ...);` but you could probably get away with `array[index](arg1, ...);` (where the three dots represent sundry extra arguments, not an actual ellipsis in the code). – Jonathan Leffler Dec 06 '17 at 20:38
  • @dbush Yes all relevant functions have the same signature. – M.Hisoka Dec 06 '17 at 20:38
  • @JonathanLeffler my function pointer array: `void (*execOp[4])(int opcode) { add, sub, div, mul };` the problem is how to filter which function to call for example by passing '0x1A' to call 'add()'. – M.Hisoka Dec 06 '17 at 20:41
  • Unbalanced braces in `main()` – Aditi Rawat Dec 06 '17 at 20:44
  • 1
    What are your possible opcodes? – Eugene Sh. Dec 06 '17 at 20:48
  • @M.Hisoka, it would be appropriate to add that array definition to your question, but note that it is not consistent with the `add()` function you actually present. It would be much more helpful to present a bona fide [mcve]. – John Bollinger Dec 06 '17 at 20:49
  • 2
    What's the possible range of opcodes? If it's not too big, create an array whose size is the largest opcode, put the relevant functions in the correct places, and set the rest to `NULL`. – dbush Dec 06 '17 at 20:49
  • 1
    Are you using C99? If so, you can use designated initializers to place the opcodes correctly in the array: `void (*execOp[])(int opcode)) = { [OP_ADD] = add, [OP_SUB] = sub, [OP_MUL] = mul, [OP_DIV] = div, ... };` which automatically places things in the right place. You can then use `if (execOp[opcode] != 0) (*execOp[opCode])(arg);` to call it. You decide what to do if the pointer is null. Error? Terminate? – Jonathan Leffler Dec 06 '17 at 20:52
  • @EugeneSh. is currently unspecified, I am looking for a general solution. – M.Hisoka Dec 06 '17 at 20:57
  • @dbush That's an option but I am searching for an another way because this would be too memory consuming. – M.Hisoka Dec 06 '17 at 20:57
  • There is no general solution that fits all. – Eugene Sh. Dec 06 '17 at 20:57
  • 1
    @JonathanLeffler that sounds nice I will try it. – M.Hisoka Dec 06 '17 at 20:58

0 Answers0