Problems with virtual functions

I'm working with nRF SDK 14.2 and the NRF52832 Dev kit, developing in C++. I have a base class with a few virtual functions and a derived class that I'm using. The code compiled, linked and flashed fine, but in debugging found that the virtual functions were not working (virtual calls in the base class calling the base implementation rather than the derived implementation).

I tried turning on rtti in the compile, in case this was required to enable virtual functions, but that is producing the following linker error:

undefined reference to `vtable for __cxxabiv1::__si_class_type_info'

Searching I've done suggests the linker needs to be directed to link to C++ runtime ( -lstdc++ ) but this option does not appear to be supported by the SEGGER linker. Linker version info is below.
C:\Program Files\SEGGER\SEGGER Embedded Studio for ARM 4.12\gcc\arm-none-eabi\bin>ld --version
GNU ld (GNU Binutils) 2.30.0.20180329

The post was edited 1 time, last by smithron99 (Jan 14th 2019, 10:12pm).

Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
Should you be entitled to support contact us per e-mail.
Alternatively our support ticketing system can be used as well: segger.com/ticket/

the only method in this chain overridden by the derived class is maxCycles(), but in this call chain, the base class implementation is called

Here's the base class definition:

Source Code

class PowerCurve

{

protected:

static const long CYCLE_MICROS = 8333;

static long _highBuffer;

static long _lowBuffer;

long _floor;

long _maxSpeed;

public:

PowerCurve(long highBuffer, long floor, long maxSpeed)

{

init(highBuffer, floor);

_maxSpeed = maxSpeed;

}

virtual ~PowerCurve() {}

void init(long highBuffer, long floor);

virtual void highBuffer(long buffer);

static long highBuffer(void)

{

return _highBuffer;

}

long delayFromPower(long power);

virtual long delayFromSpeed(long speed)

{

return _lowBuffer;

}

void floor(long aFloor);

long floor(void)

{ return _floor; }

static long lowBuffer(void)

{ return _lowBuffer; }

virtual long maxCycles(void);

int power(long delay);

long maxSpeed(void)

{ return _maxSpeed; }

virtual std::string toString(void);

};

Display All

So there are five virtual functions. I'm not sure how to examine the generated vtable from the linker, but looking at the locals in the debugger, it looks (?) like only the destructor is present in the vtable. See the attached image. I've also attached full source for the base and derived classes. The derived instance is allocated on the stack. Declared in main() like so:

If the debugger is telling the truth, then it looks like the vtable is fully populated, but not correct (see attached image). Not sure why the destructor is showing at both offsets [0] and [1]. Could the problem be that this is happening in the base class constructor, and the derived class is not deemed constructed yet? Maybe the correct vtable is not in play yet? This code is borrowed from an existing working project, but built with a different compiler. Hmmm..