tags:

views:

217

answers:

6
+4  A: 
#define call_function(fun, member) fun##_##number ()
// ------------------------^
// should be "number".

Even so, you'll only get fun_i. You can't call the preprocessor macros at runtime because they're used only in preprocessing (even before parsing and compiling).

You need to expand the loop manually.

call_function(fun, 0);
call_function(fun, 1);
call_function(fun, 2);
call_function(fun, 3);
call_function(fun, 4);
call_function(fun, 5);
call_function(fun, 6);
call_function(fun, 7);
call_function(fun, 8);
call_function(fun, 9);

Or use __COUNTER__ (needs gcc ≥ 4.3):

#define CONCAT3p(x,y,z) x##y##z
#define CONCAT3(x,y,z) CONCAT3p(x,y,z)
#define call_function(func) CONCAT3(func, _, __COUNTER__)()

call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
KennyTM
Thanks for correct my question. This example I use a loop, but in the real problem I will have to use an switch. this is slow.
drigoSkalWalker
Shouldn't it be possible to have an array of function pointers or something? It's been ages since I've even thought about C or C++ code
Bob
Note that although CPP doesn't provide loops, it's not the only preprocessor out there. It's just the only one that's built-in. You can use a more powerful preprocessor, like m4, to do more complex work at compile-time.
Ken
@drigo: What `switch`? Please show the actual code?
KennyTM
A switch is not slow. Most compilers will use a jump table unless there are very few alternatives it might use if branching.
progrmr
yeah, i know function pointer, but see the ascii table, lets say that my input is only @ % a and }, I have to make a array with 127 blocks, to catch only four, this is too expensive. but much more quickly thant a switch (if I use ten or more alternatives...)
drigoSkalWalker
@drigo: Please edit your question to show the actual problem. Your comment won't make sense without the context.
KennyTM
If you have any sort of optimizations enabled in your compiler, using a switch will not be slow (especially compared to dynamically generating and interpreting a function name at run-time). Switches are typically transformed into jump tables, where each `case` requires 2-4 assembly operations (varies based on CPU instruction set) to handle the jump. A table of function pointers would probably be faster than a switch, but might not be ideal depending on the range of `i` you are expecting.
bta
@drigo: Even if you use `switch` the compiler will still generate a ~100-element table.
KennyTM
+2  A: 

You can't do it like this. Preprocessor is the guy who plays it's role even before program is compiled. What it does is just replaces macros. So when your code gets into compiler there are no macroses at all, they are replaced by actual code.

Take a look at function pointers - that's might help you!

Andrey
+5  A: 

you need to create an array of function pointers and call through that array.

 typedef int (*pfunc)(int);
 pfunc[] = {func0,func1,func2,func3};
 for(int i = 0; i < 3; i++)
 {
     pfunc[i](arg);
  }

I am sure I have the syntax wrong somewhere - check out http://www.newty.de/fpt/fpt.html

pm100
+1  A: 

Try this (inspired by Bob's comment). You can just index into the fns array instead of using a switch.

#include <stdio.h>
#include <stdlib.h>

int fn_0() { printf("0\n"); }
int fn_1() { printf("1\n"); }
int fn_2() { printf("2\n"); }
int fn_3() { printf("3\n"); }
int fn_4() { printf("4\n"); }
int fn_5() { printf("5\n"); }

int main(char **argv, int argc)
{

  int (*fns[6])(void);
  int i;

  fns[0] = *fn_0;
  fns[1] = *fn_1;
  fns[2] = *fn_2;
  fns[3] = *fn_3;
  fns[4] = *fn_4;
  fns[5] = *fn_5;

  for(i = 0; i < 6; ++i)
    fns[i]();

}

Of course if your array is sparse (not a continuous set of integers) then you should probably use a switch.

charlieb
+1  A: 

You can't do this. It's simply not part of the C language. What you need to do is create a table that maps the possible inputs to the correct functionality. This can be as simple as a switch statement or you can use a more complicated structure like a hash that uses the input for its keys and has function pointers for values.

Chuck
A: 

In response to your issue with function pointers - all you need to do to solve the problem is create a mapping from the ten characters you're interested in to the numbers 1 through 10:

#include <string.h>

typedef int (*funcptr_t)(int);

funcptr_t func_table[11] = { func_unknown, func_ampersand, func_asterisk, func_circumflex, /* ... all the rest here */ };

/* get_index: Returns a value from 1 to 10 if c is in the allowed set, or 0 if not */
static int get_index(char c)
{
    static const char * const lookup_table[] = "&*^><!@#$%";
    char *p = strchr(lookup_table, c);

    return p ? (p - lookup_table) + 1 : 0;
}

Then to call the function, you can just do:

result = func_table[get_index(somechar)](arguments);
caf