Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

C++ pass by referenece not working as expected.

I am upgrading NIOS toolsets from 8.1 to 13.1.

In 8.1 this code compiled and functioned correctly.

In 13.1 this code compiles and mis functions. There are no warnings associated with the code.

Three code snippets to follow which declare and use a Timer class.

**************************************

Timers.hpp contains

// Timers available

enum TimerHandle

{

TMR_0 = 0,

TMR_1 = 1,

TMR_INV = 2

};

class Timers

{

public:

// Initialisation operations

static Timers* Instance();

// Interval timer functions

bool GetIntervalTimer( const TimerHandle & p_rHandle );

protected:

Timers(); // Default constructor.

~Timers(); // Destructor.

private:

// Timers member variables

static Timers* m_pThis; // Instance pointer.

public:

private:

};

**************************************

Timers.cpp contains

**************************************

# include "Timers.hpp"

// initialise static members

Timers* Timers::m_pThis = 0;

Timers* Timers::Instance()

{

if(0 == m_pThis)

{

m_pThis = new Timers();

if(!m_pThis->Init())

{

m_pThis->~Timers();

}

}

return m_pThis;

}

Timers::Timers()

{

// Record this for use by interrupt service routine

m_pThis = this;

}

bool Timers::GetIntervalTimer( const TimerHandle &p_rHandle )

{

assert( p_rHandle < TMR_INV );

// other stuff if p_rHandle is OK

return false;

}

**************************************

"MainRoutine.cpp" contains

**************************************

# include "subroutine.hpp"

void main

{

TimerHandle m_hStatusTimer; // Status timer handle.

m_hStatusTimer = TMR_0;

// Instantiate the Timers object and initialise

Timers* pTimers = Timers::Instance();

pTimers->GetIntervalTimer( m_hStatusTimer );

//

}

**************************************

so when I debug my code I can see :

  • m_hStatusTimer gets set to 0

  • Then jumps to Timers::GetIntervalTimer.

  • Inside Timers::GetIntervalTimer, p_rHandle = 0xffffdfee, so the assert comes into play - and the code stalls - as it should if the input parameter is out of bounds.

  • I assume 0xfffdfee is the address of m_hStatusTimer

My expectation is that

Inside Timers::GetIntervalTimer, p_rHandle should = 0x0, so the assert doesn't comes into play - and the code continues.

If I change the subroutine as follows the code debugs as expected.

bool Timers::GetIntervalTimer( const TimerHandle &p_rHandle )

{

TimerHandle temp;

temp = p_rHandle;

assert( temp < TMR_INV );

// other stuff if p_rHandle is OK

return false;

}

Any ideas on what is happening welcome.

Thanks

Alun

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    See that's what assuming does for you.

    Its the 'assert' that is not working, the rest of code is perfectly happy.

    The 'assert' is a macro - and I'm guessing the implementation has change to make it not work correctly with the pass by reference method.

    On to the next issue.

    Thanks

    Alun
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Oh.. just ask yourself "Will derefence of formal parameter occur when assert macro called?".

    and btw, why you are using protected constructors? It seems you need the subclass for base class. if no subs should we use private,protected modifiers?

    The question "Do you understand C++ clearly?"