Home > database >  cannot be used as a member pointer, since it is of type 'void (*)()'
cannot be used as a member pointer, since it is of type 'void (*)()'

Time:05-08

I'm trying to dereference a method pointer stored in a static array and call it from within a method, but I'm getting the following error:

error: 'chip8::Chip8::table[0]' cannot be used as a member pointer, since it is of type 'void (*)()'
     (this->*table[0])();
                    ^

Here is my class declaration (chip.hpp):

class Chip8{
  private:
    static void (*table[16])(); //function pointer table
    //...
  public:
    void cycle();
    //...
};

and here are the implementations of Chip8::cycle and Chip8::table (chip.cpp):

void (Chip8::*table[16])() = {
    &Chip8::opcode0,
    &Chip8::JP_1nnn,
    &Chip8::CALL_2nnn,
    &Chip8::SE_3xkk,
    &Chip8::SNE_4xkk,
    &Chip8::SE_5xy0,
    &Chip8::LD_6xkk,
    &Chip8::ADD_7xkk,
    &Chip8::opcode8,
    &Chip8::SNE_9xy0,
    &Chip8::LD_Annn,
    &Chip8::JP_Bnnn,
    &Chip8::RND_Cxkk,
    &Chip8::DRW_Dxyn,
    &Chip8::opcodeE,
    &Chip8::opcodeF
  };

  void Chip8::cycle(){
    opcode = (memory[pc] << 8) | memory[pc 1];
    pc =2;

    (this->*table[0])(); // error here

    if(dt > 0){
      dt--;
    }

    if(st > 0){
      st--;
    }
  }

EDIT: Here are the declarations of the functions assigned to the table:

//Function table extensions
    void opcode0();
    void opcode8();
    void opcodeE();
    void opcodeF();

    //Instructions
    void CLS_00E0();  // Clears screen
    void RET_00EE();  // Pops new pc off the stack
    void JP_1nnn();   // Jumps to nnn
    void CALL_2nnn(); // Pushes current pc to stack and jumps to nnn
    void SE_3xkk();   // Skip next instruction if Vx = kk
    void SNE_4xkk();  // Skip next instruction if Vx != kk
    void SE_5xy0();   // Skip next instruction if Vx == Vy
    void LD_6xkk();   // Set Vx = kk
    void ADD_7xkk();  // Vx  = kk
    void LD_8xy0();   // Vx = Vy
    void OR_8xy1();   // Vx |= Vy
    void AND_8xy2();  // Vx &= Vy
    void XOR_8xy3();  // Vx ^= Vy
    void ADD_8xy4();  // Vx  = Vy, if the sum is greater than 255, then VF = 1
    void SUB_8xy5();  // Vx -= Vy, if Vx > Vy, then VF = 1, otherwise VF = 0
    void SHR_8xy6();  // Vx >>= 1, if least significant bit of Vx is 1, then VF is set to 1, otherwise 0
    void SUBN_8xy7(); // Vx = Vy - Vx, if Vy > Vx, VF = 1, otherwise VF = 0
    void SHL_8xyE();  // Vx <<= 1, if most significant bit of Vx is 1, then VF is set to 1, otherwise 0
    void SNE_9xy0();  // Skip next instruction if Vx != Vy
    void LD_Annn();   // I = nnn
    void JP_Bnnn();   // Jumps to nnn   V0
    void RND_Cxkk();  // Vx = random byte & kk
    void DRW_Dxyn();  // Draws n-byte (n = height) sprite starting at Vx and Vy. If collision detected, VF = 1
    void SKP_Ex9E();  // Skip next instruction if value of Vx is pressed
    void SKNP_ExA1(); // Skip next instruction if value of Vx isn't pressed
    void LD_Fx07();   // Set Vx = delay timer
    void LD_Fx0A();   // Wait for key press and store value in Vx
    void LD_Fx15();   // Set delay timer = Vx
    void LD_Fx18();   // Set sound timer = Vx
    void ADD_Fx1E();  // Set I  = Vx
    void LD_Fx29();   // Set I = memory location of digit sprite in Vx
    void LD_Fx33();   // Store BCD representation of value of Vx in I, I 1, I 2
    void LD_Fx55();   // Store registers V0 through Vx (including) starting at memory location I
    void LD_Fx65();   // Read registers V0 through Vx (including) starting at memory location I

What is the problem and how can I fix it?

CodePudding user response:

Your table contains function pointers, not member function pointer. Just use them as function pointers without this.

My guess is all the functions assigned to the table are static functions.


For non static function use a member function pointer type for the table:

static void (Chip::*table[16])(); // member function pointer table

or more readable:

using OpType = void (Chip::*)();
static OpType table[16];

CodePudding user response:

When you wrote:

static void (*table[16])();

You're declaring a static data member named table that is an array of size 16 whose elements are pointers to a function with no parameter and return type of int.

But what you actually want is a table that is an array of size 16 whose elements are pointers to the member functions of Chip8 which you can do as shown below:

class Chip8{
  private:
//---------------vvvvvvvv------------>note the added Chip8::* indicating that a pointer to a member function instead of free function            
    static void (Chip8::*table[16])(); //function pointer table
  
  public:
    void cycle();
    void opcode0();
    
   
};
//definition for the static data member `table`
void (Chip8::*Chip8::table[16])() = {
    &Chip8::opcode0,
    
  };
void Chip8::opcode0()
{
    std::cout<<"opcode0 called"<<std::endl;
}
void Chip8::cycle(){
  
    std::cout<<"cycle called"<<std::endl;
    (this->*table[0])();
    
  }

int main()
{
    Chip8 chip;
    chip.cycle();
    return 0;
}

Working Demo.

Note that you can also use a typedef for the member function as shown below:

class Chip8{
  private:
    using type = void (Chip8::*)();              
    static type table[16]; //function pointer table
  
  public:
    void cycle();
    void opcode0();
    
   
};
Chip8::type Chip8::table[16] = {
    &Chip8::opcode0,
    
  };
void Chip8::opcode0()
{
    std::cout<<"opcode0 called"<<std::endl;
}
void Chip8::cycle(){
  
    std::cout<<"cycle called"<<std::endl;
    (this->*table[0])();
    
}
int main()
{
    Chip8 chip;
    chip.cycle();
    return 0;
}

Demo

  • Related