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

I have a problem with writing interrupt handlers in Keil ARM compiler for LPC1114. When I write program in C++ and specify --cpp compiler option all code from interrupt handlers disappears, it is replaced with infinite loop. I wrote simple program that illustrates my trouble.

#include "LPC11xx.h"           // LPC11xx definitions
#define SYSTICK_DELAY 120000   // for 10 ms systick @ 12MHz osc

void SysTick_Handler(void)
{
__NOP();
}

int main (void)
{
SystemInit();                   // from system_LPC11xx.c
SysTick_Config(SYSTICK_DELAY);  // from core_cm0.h
// Loop forever
while (1) __NOP();
}


When trying to compile this code with --cpp compiler option I get infinite loop in disasm:

SysTick_Handler PROC
EXPORT  SysTick_Handler           [WEAK]
B       .
ENDP


This is the place where __NOP() from above program must be. And it is there when I'm compiling code with --c99 compiler option or without additional options. Keil MDK version is 4.12. Can anyone tell me is there any solution or workaround ?

• As your ISR does nothing is it just being optimized away? Perhaps you could try disabling optimization or declaring something volatile in it. Dec 8, 2010 at 14:44
• Optimization is set to -level0, Optimize for Time - deselected. __NOP() is not nothing. But I also tried changing global vars in interrupt handler or calling for functions. The code provided above was simplified to be just so small to reproduce the problem. Dec 8, 2010 at 15:02
• Filed a technical support request to Keil, will repost here any answer. Dec 8, 2010 at 15:06
• Why do you need an __NOP(); call? Can't you just use a simple semicolon? Dec 8, 2010 at 15:34

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
}
}

• Thank you. This works exactly as you wrote in example. And also I can declare function in header file as extern "C" void SysTick_Handler(void); and later write my interrupt handler in classical form i.e. without extern "C". Dec 10, 2010 at 14:22
• Oh my god! Thank you for this great answer! So much time was wasted because of not knowing this ) Thank you once more!
– user2977
Feb 12, 2011 at 15:34