Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12711 Discussions

C++ pass by referenece not working as expected.

Altera_Forum
Honored Contributor II
1,339 Views

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
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
581 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
581 Views

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?"
0 Kudos
Reply