HLP: Problem with Virtual Function

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HLP: Problem with Virtual Function

Jump to solution
1,702 Views
tkvenki
Contributor III
Hi,

I have a base class
-----------------------------------------------------------------------------------------------------
class cBaseClass
{
    public:
        // functions
       cBaseClass();
        ~cBaseClass(){};
       
        void testMainLoop(void);
        virtual void test_DummyFunction(void) = 0;
        void test_NoVirtual(void);
};
-----------------------------------------------------------------------------------------------------
I have derived this class from derived class.

class cDerivedClass : public cBaseClass
{
    public:
        // functions
        cDerivedClass();
        ~cDerivedClass( void );
       
       void testCaller(void);
       void test_DummyFunction(void);            //override
};

----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------

And in the Base class

void cBaseClass:: testMainLoop(void)
{
    /*.....SOme Statements....*/
    test_DummyFunction();                // This should call the function definition of test_DummyFunction
                                                          // which is written in the Derived Class
}


THat is

void cDerivedClass:: testDummyFunction(void)
{
    int x;

     x = 2;
}
----------------------------------------------------------------------------------------------------


As we can see in the above code, I'm calling the function testDummyFunction.
The control should go to the testDummyFunction  definition which is in the derived class.
But this is not happening. The control goes to some assembly routines.

I thought some stack corruption...or something like that might have happened.
But...when I replace the function call testDummyFunction(), by testNoVirtual(),
which is not a virtual function, then the control smoothly went to the non-virtual function.

Please help me to sort out this issue.
Details:
IDE:                   Codewarrior for Coldfire
Version:             6.4 Build 6
Processor:        MCF5485
RTOS:               Threadx

Please let me know if you require further details.

Thanks,
Venkatesh





Labels (1)
0 Kudos
1 Solution
668 Views
RicardoRaupp
Contributor II

UUUaauuuu....

Afer 10 minutes of my lat port I found my problem.

I just add the pragma:

 

#pragma options align=packed

 

and now eveything is ok...

 

I used this in older designs and I thought I added it in all necessary parts of my code, but it seems I forgot...

 

Thanks

 

Ricardo Raupp

View solution in original post

0 Kudos
6 Replies
668 Views
tkvenki
Contributor III
Hi,

The issue gets more creepy,
Before I call the function ,     test_DummyFunction(); 
I have called another function. txwrap();
This function after it returns is making the this pointer in the variables window, to ZERO.
This seems to be the culprit.
Because if I avoid the txwrap() function, then the call to test_DummyFunction Works perfectly.
Because the this pointer is not corrupted.

If I put some other data here, then the this pointer remains intact.
Now the control goes to the test_Dummy function.

In my code I'm not making any modifications to the this pointer explicitly.
Why does this get corrupted?
My software architecture forces me to use a function here[which will corrupt the this pointer]. I cannot opt for other way.

Please help me out in this regard.

Compiler Guru:
I'm not able to find virtual tables, in my code.
Where do I find this?
I read in some books that in all classes which have a virtual function,
a Virtual table pointer will be created. But I cannot get how do we loate this.
Please help me out.


0 Kudos
668 Views
RicardoRaupp
Contributor II

Ooooops..sorry

 

Hi..

 

Have you solved your issue?

 

I strongly use pure virtual functions in order to build components x drivers, so that to keep a comon interface for the components I create.

I uses this feature very well ib S08 mcus (CW6.2).

It works perfectly.

 

Now I´m porting this application for ColdFire (MCF52259)  using CW7.1.

 

It is  a strange.

 

I hace a i2c class wich is derived from I_i2c class wich has pure virtual functions (it is just a interface), wich MUST be implemented in the i2c class.

Like:

// the interface (base class)

class I_i2c      
{
 private:
 public:
  I_i2c(){};
  virtual void init(uint32 baud)=0;
  virtual uint8 read(uint8 *p_out,uint8 size,uint8 device_address,const uint8 *p_reg_address,uint8 address_size)=0;
  virtual uint8 write(uint8 *p_in,uint8 size,uint8 device_address,const uint8 *p_reg_address,uint8 address_size)=0;
};

 

and the class to instantiate objects with I_i2c interface

 

class I2c : public I_i2c
{
 private:
  uint32 real_baud;
  void delay_10us(void);
  void delay_125us(void);
  void send_stop(void);
  void busy_loop(void);
  uint8 write_busy_loop(uint8 data);
 public:
  I2c();
  // base class virtual functions
  void init(uint32 baud);
  uint8 read(uint8 *p_out,uint8 size,uint8 device_address,const uint8 *p_reg_address,uint8 reg_address_size);
  uint8 write(uint8 *p_in,uint8 size,uint8 device_address,const uint8 *p_reg_address,uint8 reg_address_size);
};

 

In the main file I create a object i2c:

 

I2c i2c0;

 

when I call:

i2c0.init, it works perfectly.

 

But, I usually access this objects by a pointer  for its base class (interface)., like

 

I_i2c *p=&i2c0;// poits to the base class - interface

 

I cam call init by:

 

p->init();

 

Works fine too...

 

 

My problem is ...

 

I made the same thing for the class Uart (component) and I_uart (interface).

For my surprise for this class, I do through assembly lines when accessing it via pointer, like

 

Uart uart_0;//derived from I_uart

I_uart *p=&uart0;

 

p->init()  ///  CRASH here...!!!

 

 

Summarizing:

1- both objects ( i2c and uart_0 ) were working fine ( can be accessed by pointers) in CW6.2

2- Only i2c object is working now

3- The uart_0 object/class has the SAME approch of i2c object/class, I mean: declaration / definition etc...

 

 

I appreciate your help..it´s not easy to share virtual functions kwnowledgment...

 

Thanks

 

Ricardo Raupp

 

 

0 Kudos
669 Views
RicardoRaupp
Contributor II

UUUaauuuu....

Afer 10 minutes of my lat port I found my problem.

I just add the pragma:

 

#pragma options align=packed

 

and now eveything is ok...

 

I used this in older designs and I thought I added it in all necessary parts of my code, but it seems I forgot...

 

Thanks

 

Ricardo Raupp

0 Kudos
668 Views
RicardoRaupp
Contributor II

Hi g

0 Kudos
668 Views
ChrisJohns
Contributor I
First the destructor should be virtual when you have virtual functions. Compilers normally warn you about this so I suggest you turn on warnings and fix each one.

You have not shown where the instance of the derived class comes from that you call testMainLoop with. You may have only the base class and in that case calling test_DummyFunction is not valid. This normally results in a message along the lines of "pure virtual called" being sent to stdout. This dates back the old cfront compilers.
0 Kudos
668 Views
CompilerGuru
NXP Employee
NXP Employee
Hi Venkatesh,

I don't think the problem is in the code you showed, well at least I did not notice it.
First make sure you are not calling the virtual from within the constructor of the base class. While an object is being created, C++ does not call virtual function of derived classes, calling abstract virtual functions at this time aborts.
As second guess I would suggest to look at the object you call the virtual on. How is it created?
And then I would also check where you allocate the virtual tables.

Daniel
0 Kudos