Function lookup tables?

Discussion in 'C++' started by John Collyer, Oct 4, 2003.

  1. John Collyer

    John Collyer Guest

    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! =-----
     
    John Collyer, Oct 4, 2003
    #1
    1. Advertising

  2. "John Collyer" <> 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
     
    Victor Bazarov, Oct 4, 2003
    #2
    1. Advertising

  3. John Collyer

    WW Guest

    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
     
    WW, Oct 4, 2003
    #3
  4. "John Collyer" <> wrote in message
    news:3f7ee0db$...
    > 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.

    --
    Peter van Merkerk
    peter.van.merkerk(at)dse.nl
     
    Peter van Merkerk, Oct 4, 2003
    #4
  5. 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.
     
    Gianni Mariani, Oct 4, 2003
    #5
  6. John Collyer

    Ron Ruble Guest

    "Peter van Merkerk" <> wrote in message news:blmocb$dpfhf$-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.
     
    Ron Ruble, Oct 4, 2003
    #6
  7. Ron Ruble wrote:
    > "Peter van Merkerk" <> wrote in message news:blmocb$dpfhf$-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 ?
     
    Gianni Mariani, Oct 4, 2003
    #7
  8. John Collyer

    Ron Ruble Guest

    "Gianni Mariani" <> wrote in message news:blnj37$...
    > 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.
     
    Ron Ruble, Oct 5, 2003
    #8
  9. Ron Ruble wrote:
    > "Gianni Mariani" <> wrote in message news:blnj37$...
    >
    >>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
     
    Gianni Mariani, Oct 5, 2003
    #9
  10. John Collyer

    John Collyer Guest

    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" <> wrote in message
    news:blmocb$dpfhf$-berlin.de...
    > "John Collyer" <> wrote in message
    > news:3f7ee0db$...
    > > 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.
    >
    > --
    > 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! =-----
     
    John Collyer, Oct 5, 2003
    #10
  11. John Collyer

    John Collyer Guest

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

    "John Collyer" <> wrote in message
    news:3f802381$...
    > 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" <> wrote in message
    > news:blmocb$dpfhf$-berlin.de...
    > > "John Collyer" <> wrote in message
    > > news:3f7ee0db$...
    > > > 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.
    > >
    > > --
    > > 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! =-----





    -----= 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! =-----
     
    John Collyer, Oct 5, 2003
    #11
  12. 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.
     
    =?iso-8859-1?Q?Juli=E1n?= Albo, Oct 5, 2003
    #12
  13. Karl Heinz Buchegger, Oct 6, 2003
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Demetri
    Replies:
    0
    Views:
    346
    Demetri
    Oct 15, 2003
  2. Jack
    Replies:
    0
    Views:
    369
  3. Adrian Charteris

    XSLT Lookup Tables Help.

    Adrian Charteris, Oct 15, 2004, in forum: XML
    Replies:
    4
    Views:
    967
    Adrian Charteris
    Oct 18, 2004
  4. Replies:
    6
    Views:
    317
  5. =?Utf-8?B?Tmlja0NSXzA0?=

    Date Range lookup between tables in asp 2.0

    =?Utf-8?B?Tmlja0NSXzA0?=, Sep 18, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    662
    =?Utf-8?B?Tmlja0NSXzA0?=
    Sep 19, 2006
Loading...

Share This Page