Is C++ better in this respect? I have been trying to get started in it for a long time and it's a natural step.
In that regard: no. It retains all the complexity of C and adds its own.
The variable is only defined in motor.c as "volatile int32_t nominal_current".
A function defined in motor.c and declared in motor.h has a line that says:
nominal_current = 28000 ;
The function which sets up other variables too that are possibly also being optimized out but not causing an issue is called in main() before while(1){main program loop}.
A function called control() defined in motor.c and declared in motor.h uses nominal_current in 4 calculations and is called in the while(1) loop in main()
So if I pause after the function has run to set the variable up it has a value of 28000, if I pause in the control() function it's value is now "0".
This means the
nominal_current variable is actually not initialized. And then you assign to it 28000. But that assignment may be not atomic, so it’s possible
control sees garbage, 0, 28000, or any unexpected value arising from the assignment not being atomic.
volatile imposes an order of operations accessing
volatile variables. But doesn’t guarantee operation’s atomicity or visibility, and in particular the expected order may not be seen in multiple threads of execution. Coincidentally this trap is present not only in C or C++, but may also appear in other languages with a similar feature. The definition and behavior or
volatile is so muddy, misleading and unreliable, that in fact it’s discouraged in multithreaded code and to be replaced with platform-specific threading features. Not saying you should not use it; but each time you feel the temptation: think thrice.
If you made the variable
static const and assigned value of 28000 to it, then the compiler is effectively treating it as if it was a constant.
(1) So that would indeed make the issue go away. But I assume your goal was to have it as a variable, right? I quickly looked in the code you provided later and it seems you use it as a constant, though.
The reason for “minimal code reproducing the issue” is not only reader’s convenience, but — more importantly — because in the process of shrinking down the code the culprit is being found and understood.
(1) Modern C also has
constexpr, BTW. It’s how one makes “true” constants in C.