# STM32 interrupts and C++ don't go well together [duplicate]

I set up TIM3 to fire an interrupt in my project and it just wouldn't work. I tried everything I could and still couldn't find whats the problem. Then I created a clean project and copy/pasted only the code that sets up TIM3 and interrupts and it magically worked. I literally wasted half a day trying to find what causes the problem and it turns out... interrupts don't like C++.

I wrote my code in C++ because I needed classes in my project so naturally I renamed all my prject .c files to .cpp and also compile with the --cpp directive. Everything worked fine, no problems so far until I decided to use interrupts. So I renamed everything to .c and everything worked, renamed everything back to cpp and it stopped working.

I use Keil uVision5 and my projects are generated with STM32CubeMX (only RCC config).

Anyone had this happen to them? Any workarounds?

## marked as duplicate by bitsmack, Adam Haun, CL., Voltage Spike, dimJan 10 '17 at 21:02

• You may be having issues with C vs C++ linkage - your interrupt handler is probably being subjected to C++ name mangling, so it isn't replacing the default weak interrupt handler that CubeMX provides. – Devan Jan 10 '17 at 17:51
• I just found the solution, and it is exactly what you said. Funny how I wasted half a day looking for a solution only to find it a few minutes after posting the question. – John Jan 10 '17 at 17:52
• This actually is a very well-known problem in embedded. It surprises me somewhat that appropriately chosen search terms didn't immediately give any of the dozens of Keil-Fora, TI-fora, StackOverflow, etc links I seem to get when I try. – Asmyldof Jan 10 '17 at 18:02

I've been searching for a solution for half a day, only to find it a few minutes after I posted this question. The answer is given by this post:

Bug in Keil ARM compiler with interrupt handlers and C++?

The "weak" reference just means that the routine will be replaced by a routine in your code of the same name. When using C this is simple, the names will always be identical but C++ name mangles the functions (for function overloading etc) so the compiled name will probably not match the default ISR name. You need to wrap the function (or at least a forward reference, I'm not sure of specifics I mostly work in C) in an extern "C" wrapper to force the compiler to not mangle the name.

extern "C" { void SysTick_Handler(void) { // do whatever } }

Or you can just declare it as

extern "C" void SysTick_Handler(void);


So you don't have to wrap it.