Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Function lookup tables?

Reply
Thread Tools

Function lookup tables?

 
 
John Collyer
Guest
Posts: n/a
 
      10-04-2003
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




-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      10-04-2003
"John Collyer" <(E-Mail Removed)> wrote...
> 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


 
Reply With Quote
 
 
 
 
WW
Guest
Posts: n/a
 
      10-04-2003
John Collyer wrote:
> 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)?

--
WW aka Attila


 
Reply With Quote
 
Peter van Merkerk
Guest
Posts: n/a
 
      10-04-2003
"John Collyer" <(E-Mail Removed)> wrote in message
news:3f7ee0db$(E-Mail Removed)...
> 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[i]();
}

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.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      10-04-2003
John Collyer wrote:
> 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.


 
Reply With Quote
 
Ron Ruble
Guest
Posts: n/a
 
      10-04-2003

"Peter van Merkerk" <(E-Mail Removed)> wrote in message news:blmocb$dpfhf$(E-Mail Removed)-berlin.de...
<snip>
> 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.


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      10-04-2003
Ron Ruble wrote:
> "Peter van Merkerk" <(E-Mail Removed)> wrote in message news:blmocb$dpfhf$(E-Mail Removed)-berlin.de...
> <snip>
>
>>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.



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

 
Reply With Quote
 
Ron Ruble
Guest
Posts: n/a
 
      10-04-2003

"Gianni Mariani" <(E-Mail Removed)> wrote in message news:blnj37$(E-Mail Removed)...
> Ron Ruble wrote:
> > 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 ?


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.



 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      10-04-2003
Ron Ruble wrote:
> "Gianni Mariani" <(E-Mail Removed)> wrote in message news:blnj37$(E-Mail Removed)...
>
>>Ron Ruble wrote:

....
>
> 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

 
Reply With Quote
 
John Collyer
Guest
Posts: n/a
 
      10-05-2003
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" <(E-Mail Removed)> wrote in message
news:blmocb$dpfhf$(E-Mail Removed)-berlin.de...
> "John Collyer" <(E-Mail Removed)> wrote in message
> news:3f7ee0db$(E-Mail Removed)...
> > 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[i]();
> }
>
> 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.
>
> --
> Peter van Merkerk
> peter.van.merkerk(at)dse.nl
>
>





-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
no ADL / Koenig lookup for function calls with template parameters cgv C++ 2 10-14-2006 07:50 PM
Problem with CMapStringToPtr Lookup function Prasad C++ 4 06-19-2006 05:12 PM
Silly function call lookup stuff? Lucas Lemmens Python 8 09-28-2005 04:21 PM
Lookup like function Andy G ASP .Net 3 02-12-2005 11:59 AM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM



Advertisments