13

I have the following code

#define myfunc(a,b) myfunc(do_a(a), do_b(b))

void myfunc(int a, int b)
{
  do_blah(a,b);
}
int main()
{
    int x = 6, y = 7;
    myfunc(x,y);

    return 0;
}

I want the pre-processor to expand function myfunc only at calling. Required code after pre-processing looks like this:

void myfunc(int a, int b)
{
  do_blah(a,b);
}
int main()
{
    int x = 6, y = 7;
    myfunc(do_a(x),do_b(y));

    return 0;
}

The problem is that function definition is expanded also like this

void myfunc(do_a(int a), do_b(int b))
{
  do_blah(a,b);
}

Is there any way to make macro expands only if we are expanding a function call? I tried many solutions, and it seems impossible but I hope that some one saw situation like this..

NOTE: please don't tell me to rename the macro or function names :D

Update1: Thanks for you help. But I can only change the definition of the macro, I can't change its position and I can't change function implementation.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Yousf
  • 3,957
  • 3
  • 27
  • 37

4 Answers4

24

Use () to stop the preprocessor from expanding the function definition:

#include <stdio.h>

#define myfunc(a, b) myfunc(do_a(a), do_b(b))
/* if you have a preprocessor that may be non-standard
 * and enter a loop for the previous definition, define
 * myfunc with an extra set of parenthesis:
#define myfunc(a, b) (myfunc)(do_a(a), do_b(b))
 ******** */

int (myfunc)(int a, int b) /* myfunc does not get expanded here */
{
    printf("a=%d; b=%d\n", a, b);
    return 0;
}

int do_a(int a)
{
    return a * 2;
}

int do_b(int b)
{
    return b - 5;
}

int main(void)
{
    myfunc(4, 0);
    return 0;
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • I think some preprocessors may balk at the the recursive use of the form myfunc(xxx,xxx). I'd do #define myfunc(a,b) (myfunc)(do_a(a), do_b(b)) int (myfunc)(int a, int b) &c – Tim Schaeffer Dec 23 '09 at 17:39
  • 3
    Good point, Tim, thanks! But I think it's safe to assume the preprocessor will never enter a recursive loop (cf Standard 6.10.3.4/2 "... if any nested replacements encounter the name of the macro being replaced, it is not replaced ..."). – pmg Dec 23 '09 at 18:11
  • 1
    If you can change the function to put () around it's name, why can you not change the function's name? – Pete Kirkham Dec 23 '09 at 23:20
  • I've been wondering about that too, but didn't have the guts to ask the question directly :) – pmg Dec 23 '09 at 23:36
  • 3
    To change the function's name you have to - get approval from all the managers - update all documents - re-run test cases – Yousf Dec 24 '09 at 06:16
9

I see three possible solutions:

  • define your macro after function definition.

  • define, before the function definition, do_a() and do_b() such that they return their argument, and redefine them at your will after function definition

  • perform do_a() and do_b() inside the function:

    void myfunc(int a, int b)
    {
        do_blah(do_a(a),do_b(b));
    }
    

I have a strong preference for the latter.

mouviciel
  • 66,855
  • 13
  • 106
  • 140
4

Define the macro after the defintion of the function.

void myfunc(int a, int b)
{
  do_blah(a,b);
}

#define myfunc(a,b) myfunc(do_a(a), do_b(b))

int main()
{
    int x = 6, y = 7;
    myfunc(x,y);

    return 0;
}
Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
1

Define the macro after you define the function.

Alternatively, use a pattern like this:

#define myfunc_macro(a,b) myfunc(do_a(a), do_b(b))
#define myfunc(a,b) myfunc_macro(a,b)

.
.

#undef myfunc
void myfunc(int a, int b)
{
  do_blah(a,b);
}
#define myfunc(a,b) myfunc_macro(a,b)

.
.

int main()
{
    int x = 6, y = 7;
    myfunc(x,y);

    return 0;
}
moonshadow
  • 86,889
  • 7
  • 82
  • 122