From: Bart van Ingen Schenau on
ron(a)jennaron.com.au wrote:

> I don't want the size of the function, just the number of characters
> in the function name. Hence: sizeof(name), which does return the
> correct number but cannot be used directly as a parameter to the
> macro. It is simply substituted into the result:
>
> _ZNsizeof(MyClass)MyClasssizeof(MyFunction)MyFunctionEv

Unfortunately, the preprocessor is not powerful enough to produce the
kind of result you want.
No ifs and buts, it can not be done with the preprocessor.

>
> A number of microprocessors have an interrupt vector table at
> specified addresses in flash/rom.

How do you specify which function to call for a particular interrupt?
If this is done in C++ code, you should be able to specify the functions
by their regular name, instead of mangled:
void_func* interrupttable[size] = { &MyClass::MyFunction; } @ 0x0000

If you use a method that is outside the scope of the C++ language, like
an assembly file or some linker instructions, then your best bet is to
write a small helper program that generates the required information.
This helper program could then be integrated into your build process, so
that it is used automatically.

>
> Ronk

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
From: Ralph D. Ungermann on
ron(a)jennaron.com.au wrote:
[...]
> in my case it must be executable by the preprocessor, as the code
> passed to the compiler must have all macros expanded. Here is a
> meaningless but working sample program using the previous example that
> can be used as a test:
>
> #define DO_MANGLE(theclass, L1, thename, L2) \
> _ZN ## L1 ## theclass ## L2 ## thename ## Ev
>
> #define TEST_MACRO(theclass, L1, thename, L2) \ // see below!!!
> DO_MANGLE(theclass, L1, thename, L2)()
[...]
> However, what I want is the macro:
>
> #define TEST_MACRO(theclass, thename) \
> <a little bit of magic to assign numerical values to L1 and L2> \
> DO_MANGLE(theclass, L1, thename, L2)()

The preprocessor does _text_ replacement.
Only after an `#if', it will interpret the expression and calculate an
integer. But by no means, it will convert back the result to a token.

In other words: the token sequence `(1+2)<3' will always be that;
usually, it will be interpreted later by the compiler, so you won't
notice the difference -- unless you trap into operator precedence issues:

#define X 1+2
....
int i = X*2; // == 5 (!)



Things are different, if you want to use the gcc `alias' keyword, which
takes a _string_ argument interpreted by the compiler. The following
code compiles and prints "f2xy() called":


#include<iostream>

// prepend "f<n>" to a string literal s
// (<n> = number of characters in s):
#define fNS( s ) sizeof s==1 ? "f0" s : sizeof s==2 ? "f1" s : \
sizeof s==3 ? "f2" s : sizeof s==4 ? "f3" s : \
"NAME_TOO_LONG__" s

extern "C" void f2xy()
{
std::cout << "f2xy() called";
}

void f () __attribute__ ((weak, alias (fNS( "xy" ))));

int main ( int argc, char **argv )
{
f();
return 0;
}


Notes:
- you may write:
alias( x==1 ? "yes" : "no" )
but not:
void x==1 ? yes : no ();
The string is evaluated, the function name is only macro-expanded.

- as said, you cannot stringify an expression to the decimal
representation of its result value.
Instead, the fNS macro has to name `all' possible numbers.

- With two string parameters (say, up to 20 characters), the alias
argument has to list 400 atomic strings like "_ZD<x>Class<y>Func".
It will be tricky not to list them all by hand, but it will be
even harder for somebody else, to understand this piece code.

regards, Ralph