Closed subhacom closed 2 months ago
With a few print statements, it looks like an issue with multiple inheritance and virtual function. Putting print statements:
void ChanCommon::vSetEk( const Eref& e, double Ek )
is not called when HHChannel.Ek is set, void ChanBase::setEk( const Eref& e, double Ek )
does get called, but although it has a call to vSetEk
which should have been inherited by HHChannelBase
from ChanCommon
above, that function does not get called.The debug prints are inserted as follows:
void ChanBase::setEk( const Eref& e, double Ek )
{
cout << "ChanBase::setEk Ek set:" << Ek << endl;
vSetEk( e, Ek );
cout << "Ek retrieved: " << vGetEk( e ) << endl;
}
And the output shows some possibly garbage value:
>>> import moose
>>> c = moose.HHChannel('c')
>>> c.Ek
ChanBase::getEk 3.39519e-313
2.121995791e-314
>>> c.Ek = 2
ChanBase::setEk Ek set:2
Ek retrieved: 2.97079e-313
>>>
In contrast, setting Xpower
works fine. vSetXpower
is implemented in HHChannel.cpp
and is called in its parent class's HHChannelBase::setXpower
.
Edit: The inheritance seems to be a classic diamond shape:
class ChanCommon: public virtual ChanBase
class HHChannelBase: public virtual ChanBase
class HHChannel : public HHChannelBase, public ChanCommon
ChanBase [ChanBase::setEk calls virtual ChanBase::vSetEk]
// \\
// \\
ChanCommon HHChannelBase
ChanCommon::vSetEk
\ /
\ /
HHChannel
[HHChannel::vSetEk calls ChanCommon::vSetEk]
With some debug prints, the Ubuntu/gcc build takes a different run path from the Windows/MS BuildTools, which is quite baffling. I checked with a minimal example that MSBuild Tools does work fine for the diamond-shaped inheritance like above.
Ubuntu/gcc:
> python -c "import moose; c = moose.HHChannel('c'); c.Ek = 3; print(c.Ek)"
ChanBase::setEk: current value Ek=ChanCommon::vGetEk: Ek = 0
0, setting to:3
ChanCommon::vSetEk: Setting Ek to 3
ChanCommon::vSetEk: Ek = 3
**** Ek retrieved: ChanCommon::vGetEk: Ek = 3
3
ChanBase::getEk ChanCommon::vGetEk: Ek = 3
3
ChanCommon::vGetEk: Ek = 3
3.0
Windows/MS BuildTools
> python -c "import moose; c = moose.HHChannel('c'); c.Ek = 3; print(c.Ek)"
ChanBase::setEk: current value Ek=7.21479e-313, setting to:3
**** Ek retrieved: 4.03179e-313
ChanBase::getEk 3.39519e-313
2.121995791e-314
Thus the print statements inside ChanCommon::vSetEk()
and ChanCommon::vGetEk()
are never carried out in the Windows version, although they work as expected in the Ubuntu build!
Update: partially fixed by making ChanBase::~ChanBase()
virtual. This fixed Ek
setting, but not Gbar
. Moreover, the debug prints in the ChanCommon::vSetEk(...)
are still not executed.
It seems that the virtual function table is messed up on Windows. The call to vSetGbar()
in ChanBase::setGbar()
actually calls HHChannel::vSetYpower()
.
One more issue found and fixed was data member modulation_
was defined in both HHChannelBase
and ChanCommon
.
Needs closer inspection.
Fixed in #485
On Windows it seems that when an object is created and its attributes are assigned values inside a function, the attribute values do not persist after returning from the function. Minimal working example:
Output: