This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000 v6.4.9: Virtual functions

Guru 20045 points

Hello,

For virtual functions, I previously thought the c++ compiler would create a function lookup table, possibly in RAM.  After creating a simple test case with several classes derived from a base class, I noticed the code jumps directly to each derived class function that was declared as virtual in the base class.

Should I expect this always to be the case?

The reason I ask is, as a safety concern, I  don't want to have function pointers in RAM.

Thanks

Stephen

  • Yes, virtual function pointer are stored in the virtual function table, but this table is in the .const section (.econst for C2000).  You can put this section in FLASH or ROM.

    Make sure your test case is calling a virtual function through a pointer to a base class.  Here is a test case which demonstrates a virtual function call through the virtual function table:

    #include <stdio.h>
    
    class B
    {
      public:
        virtual void who() { puts("I am B"); }
    };
    
    class D : public B
    {
      public:
        virtual void who() { puts("I am D"); }
    };
    
    int main()
    {
        B *b = new D;
        b->who();
    }
    
  • Hello,

    Why do I need to create a pointer to the base class?

    Why not:

    class B
    {
      public:
        virtual void who() { puts("I am B"); }
    };
    
    class D : public B
    {
      public:
        virtual void who() { puts("I am D"); }
    };
    
    D d;
    
    int main()
    {
        d.who();
    }

    Also, my base class functions are pure virtual functions.  However, whether or not the functions are just virtual or pure virtual, the assembly code for d.who() is a jump to an absolute address.

    Assembly Code:

    23          d.who();
            main():
    008a98:   8F009128    MOVL         XAR4, #0x009128
    008a9a:   76408A7D    LCR          who
    24          return 0;
    008a9c:   9A00        MOVB         AL, #0x0
    25      }
    008a9d:   0006        LRETR        
    
    
            D::who():
    008a7d:   FE02        ADDB         SP, #2
    008a7e:   A842        MOVL         *-SP[2], XAR4
    008a7f:   8F00924E    MOVL         XAR4, #0x00924e
    008a81:   764087B0    LCR          puts
    008a83:   FE82        SUBB         SP, #2
    008a84:   0006        LRETR        

    Stephen

  • This is a fundamental feature of C++, polymorphism. The only time "virtual" comes into play is if you are calling a function through a pointer to a polymorphic class. If you are calling it with the "." operator, the class of the object is known at compile time and you get a direct call. However, if it is through the "->" operator, the compiler doesn't know whether you have an object that is exactly the type to which the pointer types, or some derived type. See www.cplusplus.com/.../polymorphism
  • Ok. That answers my question;however, your answer made me question my use of the virtual keyword.

    For my situation, I am using virtual to place requirements on what member functions and data the inherited class must have.

    Isn't that another purpose for using the virtual keyword?

  • That's more of a secondary purpose. It's the difference between a regular base class and an abstract base class. The virtual keyword is meant to enforce the interface, so that you can pass a derived object where a base object is expected, and it will still work. It's not meant to enforce things the compiler could check.
  • What I am implementing is an Java interface in c++.
    stackoverflow.com/.../how-to-implement-interfaces-in-c

    Thanks
    Stephen