Function lookup tables?

J

John Collyer

Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

Thanks

John Collyer
 
V

Victor Bazarov

John Collyer said:
In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?

You would use an array of pointers to functions. If all of them
have the same type (number, order, and types of arguments and the
return value types), of course.
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

#include <iostream>

void print3(int i) {
std::cout << " " << i << std::endl;
}

void print5(int i) {
std::cout << " " << i << std::endl;
}

void print7(int i) {
std::cout << " " << i << std::endl;
}

int main() {
void (*FUNCTION[])(int) = { print3, print5, print7 };
for (int i = 0; i < 20; ++i)
FUNCTION[i % 3](i); // call from a table
return 0;
}

Victor
 
W

WW

John said:
Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup
tables. If anyone could help I would appreciate it.

How about a static (initialized) array of function pointers? Or - depending
on what you do - OO and inheritance (vtable)?
 
P

Peter van Merkerk

John Collyer said:
Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

Try this:

#include <iostream>
using std::cout;

typedef void(*func_ptr)();

void func1()
{
cout << "func1()\n";
}

void func2()
{
cout << "func2()\n";
}

void func3()
{
cout << "func3()\n";
}

int main()
{
func_ptr func[3] = {func1, func2, func3};
for(int i = 0; i < 3; ++i)
{
func();
}

return 0;
}

Depending on the optimization capabilities of your compiler the resulting
code may be as fast as the assembler equivalent.

Note that in C++ polymorphism might be a more appropriate solution than
using function pointers or switches.
 
G

Gianni Mariani

John said:
Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

There are posts that indicate how to do what you're looking for and
they're fast.

However, consider that C++ has another mechanism that is more extensible
and this may solve you problem more effectively ( I don't know, for sure
- it's just an idea spawned by problems I had with function tables.)

C++ allows you to have polymorphic objects - i.e.


struct Poly
{
virtual void WantACracker( Cracker & food ) = 0;

virtual void Say( std::string & words ) = 0;
};


struct Poicephalus : Poly
{
virtual void WantACracker( Cracker & food )
{
if ( food != SunflowerSeed )
{
Say( "YUCK" );
}
}
};


struct Psittacus : Poly
{

Poly()
: fed_count(0)
{
}

int fed_count; // state associated with this Poly

virtual void WantACracker( Cracker & food )
{
if ( food != Ritz )
{
Say( "YUCK" );
}
fed_couint ++;
}
};


Poly * Parrots[] = { new Poicephalus, new Psittacus, new Psittacus };


int main()
{
Parrots[ 1 ]->WantACracker( Ritz );

Parrots[ 0 ]->WantACracker( SunflowerSeed );
}


The cost of the virtual overhead depends greatly on how you use it but
it is usually no more than 2 indirections and a call on most compilers.
(compared to one indirection and call with a function table). However
the flexibilty of having state associated with the function is usually
far more of a performance advantage than you're giving up.
 
R

Ron Ruble

Peter van Merkerk said:
Note that in C++ polymorphism might be a more appropriate solution than
using function pointers or switches.

Or might not. This kind of thing is particularly useful when the
decision about which function should be used isn't made at
compile time.
 
G

Gianni Mariani

Ron said:
Or might not. This kind of thing is particularly useful when the
decision about which function should be used isn't made at
compile time.


How does the "decision not at compile time" change the polymorphic
suggestion ?
 
R

Ron Ruble

Gianni Mariani said:
How does the "decision not at compile time" change the polymorphic
suggestion ?

Forgive me, I realize now that I didn't state my thoughts
clearly.

I was thinking of several apps I've worked on where
specific operations were performed based on interpreting
commands in a text file, effectively a user scripted
operation, using functions in a module loaded at
run-time.

In these cases, the -logical- operation was based on
the index into a table of function pointers, where the
index had a meaning known to the programmer
(startup code, load file, shutdown, etc.).

The actual function the pointer was set to was provided
by the dynamic module at run time, based on values
in a text file. Certainly, there are other ways to do this,
including some methods using polymorphism.

But in the specific cases I was thinking of, using a table
of function pointers was clean and simple.

Not that a polymorphic solution would be bad, just
that the table of function pointers was perfectly
adequate, and in the cases I was thinking of , it
eliminated additional design effort.
 
G

Gianni Mariani

Ron said:
....

Not that a polymorphic solution would be bad, just
that the table of function pointers was perfectly
adequate, and in the cases I was thinking of , it
eliminated additional design effort.

I've implemented both function table and polymorphic approaches in a
scenario like this one and I have found the polymorphic system to be
more easily extensible and hence in general less design effort.

I suppose we can chalk this off to different experience.

G
 
J

John Collyer

The c code for function lookup table works great, but?
I have the lookup table in a class as a member of that class.
I want to initialize the function lookup table array to my member
function calls of the class inside of the constructor for the class.
What is the correct code to initialize the function pointer array
in the constructor? I have:

inside the class header file

typedef void(*func_ptr)(); // declare pointer to function

class myclass
{
public:
myclass();
virtual ~myclass();

func_ptr Functions[5]; // declare the function pointer array

char F0(size_t address); // member functions
char F1(size_t address);
char F2(size_t address);
char F3(size_t address);
char F4(size_t address);

};

Inside the class source cpp file

myclass:myclass()
{
Functions[] = { F0,F1,F2,F3,F4}
}
myclass::~myclass()
{
}

char myclass::F0(size_t address)
{
}

char myclass::F1(size_t address)
{
}

char myclass::F2(size_t address)
{
}

char myclass::F3(size_t address)
{
}

char myclass::F4(size_t address)
{
}

The actual function pointer lookup table array is 256 functions or pointers
to functions, so the initialization list inside the constructor is quite
long and uses more then one line. Everything works except I get errors with
the array initialization list in the constructor; errors dealing with the
initialation of the array.

syntax error : ']'
error C2143: syntax error : missing ';' before '{'
error C2143: syntax error : missing ';' before '}'
error C2059: syntax error : ']'
syntax error : missing ';' before '{'
error C2143: syntax error : missing ';' before '}'

Any help?

John Collyer

Peter van Merkerk said:
John Collyer said:
Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

Try this:

#include <iostream>
using std::cout;

typedef void(*func_ptr)();

void func1()
{
cout << "func1()\n";
}

void func2()
{
cout << "func2()\n";
}

void func3()
{
cout << "func3()\n";
}

int main()
{
func_ptr func[3] = {func1, func2, func3};
for(int i = 0; i < 3; ++i)
{
func();
}

return 0;
}

Depending on the optimization capabilities of your compiler the resulting
code may be as fast as the assembler equivalent.

Note that in C++ polymorphism might be a more appropriate solution than
using function pointers or switches.
 
J

John Collyer

Ignore any typos the source is good except howto initialize the function
pointer array inside the constructor

John Collyer said:
The c code for function lookup table works great, but?
I have the lookup table in a class as a member of that class.
I want to initialize the function lookup table array to my member
function calls of the class inside of the constructor for the class.
What is the correct code to initialize the function pointer array
in the constructor? I have:

inside the class header file

typedef void(*func_ptr)(); // declare pointer to function

class myclass
{
public:
myclass();
virtual ~myclass();

func_ptr Functions[5]; // declare the function pointer array

char F0(size_t address); // member functions
char F1(size_t address);
char F2(size_t address);
char F3(size_t address);
char F4(size_t address);

};

Inside the class source cpp file

myclass:myclass()
{
Functions[] = { F0,F1,F2,F3,F4}; // semi colen is there typo
}
myclass::~myclass()
{
}

char myclass::F0(size_t address)
{
}

char myclass::F1(size_t address)
{
}

char myclass::F2(size_t address)
{
}

char myclass::F3(size_t address)
{
}

char myclass::F4(size_t address)
{
}

The actual function pointer lookup table array is 256 functions or pointers
to functions, so the initialization list inside the constructor is quite
long and uses more then one line. Everything works except I get errors with
the array initialization list in the constructor; errors dealing with the
initialation of the array.

syntax error : ']'
error C2143: syntax error : missing ';' before '{'
error C2143: syntax error : missing ';' before '}'
error C2059: syntax error : ']'
syntax error : missing ';' before '{'
error C2143: syntax error : missing ';' before '}'

Any help?

John Collyer

Peter van Merkerk said:
John Collyer said:
Hi,

In assembly language you can use a lookup table to call functions.

1. Lookup function address in table
2. Call the function

Like:

CALL FUNCTION[INDEX]

FUNCTION DD FUNC1, FUNC2, FUNC3

FUNC1:
FUNC2:
FUNC3:
RET

How can I do this in C++ I would like it to be reasonably fast also?
The way I am doing it now is with a big switch statement. The switch
uses the index number for lookup. This seems like a bad way to do
what I'd would like. The preferred way would be with the lookup tables.
If anyone could help I would appreciate it.

Try this:

#include <iostream>
using std::cout;

typedef void(*func_ptr)();

void func1()
{
cout << "func1()\n";
}

void func2()
{
cout << "func2()\n";
}

void func3()
{
cout << "func3()\n";
}

int main()
{
func_ptr func[3] = {func1, func2, func3};
for(int i = 0; i < 3; ++i)
{
func();
}

return 0;
}

Depending on the optimization capabilities of your compiler the resulting
code may be as fast as the assembler equivalent.

Note that in C++ polymorphism might be a more appropriate solution than
using function pointers or switches.

 
?

=?iso-8859-1?Q?Juli=E1n?= Albo

John Collyer escribió:
typedef void(*func_ptr)(); // declare pointer to function

class myclass
{
public:
myclass();
virtual ~myclass();

func_ptr Functions[5]; // declare the function pointer array

Make Functions static.

static func_ptr Functions [5];

And intialize it in the .cpp file outside any function as:

func_ptr myclass::Functions []= { F0, F1, F2, F3, F4 };

Regards.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top