# Function Pointer Arguments

This topic is 4480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm tring to create a simple VM, and one of the things I wanted to do was to use an array of function pointers. Using the opp-codes as indexes to the proper functions should be more efficient than using a massive switch statement to find the right function. My problem is somewhere with the function pointers. Here is the compiler error I'm getting: error C2064: term does not evaluate to a function taking 2 arguments For simlpicity, I have not included the complete program, but have re-written a snippet that shows how I did it, and gives the same error: First the header
//cTest.h

#ifndef CTEST_H
#define CTEST_H

#include <stdio.h>

class cTest
{
public:
void run();		//called from outside

private:
void foo(int a, int b);				//This a function that I want to run
void (cTest::*pFoo)(int a, int b);	//This is a function pointer, with the same arguments as the function
};	//cTest

#endif


Then the source
//cTest.cpp
//Implementation of cTest.h

#include "cTest.h"

// This is the function we're trying to get to
void cTest::foo(int a, int b)
{
printf("%d %d\n",a,b);	//Just enough to see if it works
}	//foo

//Called from outside
void cTest::run()
{
pFoo = foo;				//Point the function pointer to the actual function
pFoo(1,2);				//Now try to execute the function

//I've also tried the following:
//pFoo=&cTest::foo;
//cTest::pFoo(1,2);

}	//run


Finally the shell
// main.cpp

#include "cTest.h"

void main()	//program entry
{
cTest TEST;
TEST.run();
}	//main


I'm using MS VC++.net (2003) Any help would be appreciated

##### Share on other sites
Member function pointers allways need a "this" argument supplied, and it's not infered from context. Try:
this->*pFoo(1,2);

You can do similar with the dot member:
cTest & self = *this;self.*member_function(1,2); //works with full variables too

-Mike

(Also, for the record, I believe for compliance with ISO C++ you need to be fully explicit with your member function - e.g. "pFoo = &cTest::Foo;")

##### Share on other sites
Nope, it's still complaining about the arguments.
The only thing that does work is if I call the argument without arguments
pFoo;//orcTest::pFoo;

It compiles, but doesn't do what it's supposed to (Obviously), and in the case of the full program, creates a nasty run-time error.

##### Share on other sites
You may need brackets, which I frogot: (this->*pFoo)(1,2);

Also, you're not calling it with that last syntax posted... It's just a no-op, just like these:

3;
variable; //where variable is a variable of some type

Also, it may be worth using Boost's libraries instead:

void (cTest::*pFoo)(int a, int b);boost::function< void( int , int ) > pFoo;pFoo = foo;pFoo = boost::bind( &cTest::Foo , this );pFoo(1,2); //stays the same when using boost::function

Boost Homepage

boost::function is nice in that it's generalized so that it works well with nonmember functions, member functions, and functors.

##### Share on other sites
Thank you ever so much, it finally works!

##### Share on other sites
Quote:
 Original post by methinksThank you ever so much, it finally works!

##### Share on other sites
Just so you know, performance wise, your not going to beat a switch statement with function pointers. There are other uses for function pointers in a VM though, so it's good to know.

##### Share on other sites
Quote:
 Original post by RAZORUNREALJust so you know, performance wise, your not going to beat a switch statement with function pointers. There are other uses for function pointers in a VM though, so it's good to know.
That's a rather general statement.
It really depends upon the range of values, the number of cases, and the frequency of the cases, in the switch statement etc.
Obviously if there are enough cases which are reasonably equally frequent etc, a hashmap of function pointers for example, will win.

In summary: Whatever the constant factor, O(1) will beat O(n) when n is high enough.

btw it's great to see people like methinks expending required effort to make a simple program to demonstrate their problem. Beginners take note!
Half the time, doing that kind of thing can solve the problem anyway, avoiding the need to post at all.

##### Share on other sites
Now I'm curious how bad a switch would have to be in order for function pointers to be faster. 1,000's of entries? 10,000's?

##### Share on other sites
Quote:
 Original post by Shannon BarberNow I'm curious how bad a switch would have to be in order for function pointers to be faster. 1,000's of entries? 10,000's?

My official guess would be "it depends".

If the dispatch gets called every once in a blue moon, I'd guess function pointers would usualy be faster, although quite possibly not directly (this would be due to fewer page faults on total/average, an aftereffect of less data loaded/displaced by the loading of pages containing all/mostly switch statement lookup data).

If the dispatch gets repeatedly called during some algorithm or the like, I would say again - "it depends". The moment the extra cache needed to store this table exceeds the amount left over from the algorithm, and you'll be using the next higher up section of memory a lot more, which means it'll have been the cruical factor in a large slowdown.

##### Share on other sites
In this case it would probably get called several hundred times per game cycle, as each object's behavior is script based.

As for the number of cases in the switch, there would probably only be a few (less than 20) as I'm basing the whole thing on a Risc concept (It would actually vary some, as individual objects can add specific instructions as needed...)

Also, I'll look into Boost. Thanks for the heads up!

##### Share on other sites

This topic is 4480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628654
• Total Posts
2984055

• 10
• 9
• 9
• 10
• 21