Mangle functions

Ron Kreymborg
Mon Jan 28 19:25:00 GMT 2008

> Why not simply give the handlers C linkage?  That's a much cleaner and
> simpler
> solution, and it's what everyone else does AFAIAA.

That's the easy way and also the way I have done it in the past:


The ISR macro gives the vector "C" status so the linker can find the
vectors, and the TimerOverflow method is public. But for just those reasons
it is not the way it should work in C++. 

The interrupt handler should not be public. Nothing outside the driver class
needs to or should know anything about interrupt handlers. The language
should provide for entities like interrupt handlers.

>> #define CLASS_ISR(theclassname, themethodname) \
>>  ISR(theclassname) ISR_ALIASOF(gcc_mangle(theclassname, 
>> themethodname)); \  void theclassname::themethodname(void)
> As written this is impossible, since the mangling includes the number 
> and types of arguments.

Interrupt routines never have parameters.

> BTW: In your example you used a non-static method. You probably know 
> that you have to make sure that the this-pointer is passed accordingly 
> in this case. 

The interrupt class does not need a this pointer as it neither calls other
methods in its class or accesses any private class data, so the interrupt
method itself can correctly be non-static. Here is a barely useful example:

class CTimer0Interrupt

    void TIMER0_OVF_vect(void) __attribute__ ((signal, __INTR_ATTRS)); 

class CTimer0
    friend class CTimer0Interrupt;
    bool GetOverflowFlag(void);

    void SetOverflowFlag(void);

    volatile bool       mOverflowFlag;
    CTimer0Interrupt    mTimer0Interrupt;

and the actual interrupt in the instance of CTimer0Interrupt using the macro
above would be:

CLASS_ISR(CTimer0Interrupt, TIMER0_OVF_vect) 
    TCNT0 = TIMER0_TIMEOUT;     // restart the timeout
    Timer0.SetOverflowFlag();   // tell our friend

Because it is a friend of the peripheral driver class, it can call methods
in the driver class and thus cause consequences in that driver class. By
itself it need only manage the various registers, etc concerned with
configuring, managing, and releasing the interrupt hardware concerned, none
of which require a this.

> - a script that scans through a given set of source files for occurrences 
> of gcc_mangle, and runs the above (or equivalent) with 
> the macro's args, and appends the results in the form of a #define to 
> the generated header.

Yes, I am starting to think a pre- preprocessor is the only way. However, as
I mentioned, in the version of gcc I am using (avr-gcc) interrupt functions
are always mangled exactly the same way. The only unknowns are the number of
characters in the class and interrupt vector names. The former could be done
manually I suppose but the latter typically looks like __vector_1 or
__vector_13, and different processors have different numbers of interrupting
peripherals so the 9/10 boundary is not that easy. If I keep my macro:

CLASS_ISR(theclassname, theinterruptname)

the preprocessor can look for this, look up the interrupt vector reference,
compute the two lengths, and then build the correct statements for gcc as it
re-writes the file. Something like:

extern "C" void __vector_16(void)
void CTimer0Interrupt::__vector_16(void)

Note that this declares the interrupt vector public and "C" for the linker,
but not the class method - the latter is invisible within the C++
application. For versatility I could provide the mangle description as a
command parameter, something like:
    -m _ZN%d%s%d%sEv

Seems a lot of work for something the language should provide, and it
depends on mangling always being done the same way, but I'll give it a go. 

I would be interested in any further comments.

Ron Kreymborg

E-mail message checked by Spyware Doctor (
Database version: 5.09080

More information about the Gcc-help mailing list