Function Pointer Arguments

Started by
9 comments, last by methinks 18 years, 7 months ago
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
Advertisement
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;")
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.
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.
Thank you ever so much, it finally works!
Quote:Original post by methinks
Thank you ever so much, it finally works!


Glad to hear :-).
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.
___________________________________________________David OlsenIf I've helped you, please vote for PigeonGrape!
Quote:Original post by RAZORUNREAL
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.
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.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
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?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Quote:Original post by Shannon Barber
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?


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.

This topic is closed to new replies.

Advertisement