|
Prev: which one of the following code is efficient
Next: How to compile the following on Win64bit using Visual Studio2005 x64
From: Bart van Ingen Schenau on 24 Jan 2008 13:58 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 1 Feb 2008 06:50
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 |