2020-12-03 01:10 AM
I have found a problem when deriving a class from two base classes.
class BaseA
{
public:
BaseA() {}
virtual int GetNumber() const {return 42;}
};
class BaseB
{
public:
BaseB() {}
virtual int32_t MathConfuscator(int32_t input) {return input * 97 % 5;}
};
class DerivedC : public BaseA, public BaseB
{
public:
DerivedC() {}
int GetNumber() const override {return 10;}
int32_t MathConfuscator(int32_t input) override {return input * 10;}
};
Running these classes in a program e.g.:
int main()
{
DerivedC myDerive;
int64_t myTick = 4078;
int32_t tmp = ((BaseA*)&myDerive)->GetNumber();
if(myTick == ((BaseB*)&myDerive)->MathConfuscator(tmp))
return 1;
}
The first function call GetNumber() is executed correctly and jumps into the DerivedC function while the MathConfuscator function call crashes with a hard fault.
I have tested this on an STM32G031 Nucleo-32 evaluation board using the STM32G031K8T6 procesor. The compiler chain is "9 2020-q2-update".
To me it is unclear why I do get a hard fault when running this code. If the code would be wrong I would expect a compiler error or a linker problem.
Can you give me a hint what I am doing wrong or where I might look for an answer to this problem?
Thanks,
Rasmus Kölln
Solved! Go to Solution.
2020-12-03 10:15 AM
works here for a similar chip (the closest I have) and default settings:
arm-none-eabi-g++ "../Core/Src/moin.cpp" -mcpu=cortex-m0plus -std=gnu++14 -g3 -DSTM32G071xx -DUSE_HAL_DRIVER -DDEBUG -c -I../Core/Inc -I../Drivers/STM32G0xx_HAL_Driver/Inc -I../Drivers/STM32G0xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32G0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"Core/Src/moin.d" -MT"Core/Src/moin.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/moin.o"
Anyway, the result is 100.
2020-12-03 04:58 AM
Could you try proper C++ casting, not old C type pointer casting.
2020-12-03 07:53 AM
Changing the code of the main function into
int main()
{
DerivedC myDerive;
int64_t myTick = 4078;
int32_t tmp = dynamic_cast<BaseA*>(&myDerive)->GetNumber();
if(myTick == dynamic_cast<BaseB*>(&myDerive)->MathConfuscator(tmp))
return 1;
}
did not change anything on the behavior, I still end up with a hard fault.
The assmebler code of both versions crash at the same address on the same instruction:
stmia r0!, {r2}
where r0 and r2 have the same value.
2020-12-03 10:15 AM
works here for a similar chip (the closest I have) and default settings:
arm-none-eabi-g++ "../Core/Src/moin.cpp" -mcpu=cortex-m0plus -std=gnu++14 -g3 -DSTM32G071xx -DUSE_HAL_DRIVER -DDEBUG -c -I../Core/Inc -I../Drivers/STM32G0xx_HAL_Driver/Inc -I../Drivers/STM32G0xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32G0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"Core/Src/moin.d" -MT"Core/Src/moin.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/moin.o"
Anyway, the result is 100.
2020-12-04 02:17 AM
Dear KnarfB,
I have compiled the code with the flags you have put and it works fine now.
I did not have the flag mcpu=cortex-m0plus in my compiler flags. I had -mthumb instead. Changing that flag did the trick - so thanks a lot for posting the compiler flags.