Thread: Playing with macros (#define doubt)

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    16

    Playing with macros (#define doubt)

    The following code is supposed to take input and call a specific function if found, but due to some mistake of mine it is trying to call the variable name itself.
    Code:
    #define call_exec(ex) \
    	if( exec_ ##ex != NULL ) \
    		exec_ ##ex; \
    	else \
    		printf("Error: Unknown Function (%d)",ex);
    it is called as call_exec(excec); (where exec is a int that was extracted from the user input) but a error is shown up as if it was trying to call exec_exec (which doesn't exist). The behavior I wanted when i wrote it was to call, for example, exec_1, exec_100, exec_300 etc.
    Would you mind to point out what I've done wrong?
    Thank you for your time.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    The #define is resolved at preprocess time, which is even before compile time. After compile time is runtime, so, no way can your user input gotten at runtime change the preprocessor directive.

    To get equivalent functionality, you can build a function table, (paired entries of ints and function addresses) where an int the user picks corresponds to the function address you need to call, and then it's just a matter of calling the function at the address that matches the user's input.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Posts
    16
    I guess you didn't get what I meant (or, perhaps, I'm pointing non-sense), because I have other defines that set data during the runtime, for example:
    Code:
    #define seta(comando,str,flag) \
    	if (strcmp(str,#comando)==0&&(flag==0||flag==1)){\
    		dxc[Xhis->m].flag.comando = flag;\
    		sprintf(global_str,"%s flag has been set to %s",#comando,flag?"On":"Off");\
    		global_show(Xhis->fd,global_str);\
    		return 0;\
    	}
    where str and flag are taken in real-time from the user input (and it works) - `comando` is predefined in some areas.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The root of your problem is that you can't tokenize at run time. That is to say, you can't convert the contents of some variable to a token (i.e. function name or part thereof) at runtime. The macros are evaluated in the preprocessor stage, before the code is even compiled, let alone linked or run.

    When you call the macro, like so "call_exec(variable_name)", it combines exec_ with what you passed in, variable_name, not the value of that variable (which isn't known until run time). Thus you get "exec_variable_name", which is not a known function (and would evaluate the same no matter what the contents of varaible_name). Your best bet is probably to map numbers to function pointers like so:

    Code:
    struct func_map {
        int key;
        float (*exec_func)(int, char *);
    } map[3] = {
        {1, exec_1},
        {100, exec_100},
        {300, exec_300}
    };
    Then you make a little function to search through map for a given key and return you the function pointer (map[i].exec_func).

    As a side note, if you still use that macro, you need a set of parentheses, like this:
    Code:
    exec_##ex();
    Otherwise, your macro turns into the following statement:
    Code:
    exec_variable_name;
    Which does nothing.

  5. #5
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I'm not sure you are comparing apples to apples here.

    In your seta macro, you are swapping out pointers at compile time with pointers at runtime.

    In your first example you are trying to swap out integers at runtime with function names (aka, function addresses) at compile time.

    Print out the intermediate file (from your compile) and see what it looks like.
    Mainframe assembler programmer by trade. C coder when I can.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Accessing syscalls from C
    By lilcoder in forum C Programming
    Replies: 17
    Last Post: 09-19-2007, 02:27 PM
  2. C Programming 2d Array Question
    By jeev2005 in forum C Programming
    Replies: 3
    Last Post: 04-26-2006, 03:18 PM
  3. Directional Keys - Useing in Console
    By RoD in forum C++ Programming
    Replies: 38
    Last Post: 10-06-2002, 04:42 PM
  4. FAQ: Directional Keys - Useing in Console
    By RoD in forum FAQ Board
    Replies: 38
    Last Post: 10-06-2002, 04:42 PM