heethesh
heethesh

Reputation: 401

Passing macro arguments to macro function

How do I pass macro arguments along with another integer variable to a macro function?

#define SUM(X, Y, Z) X + Y + Z
#define FOO 1, 2

void print(int a, int b)
{
    printf("Sum: %d", a + b);
}

int main(void) 
{
    // Normal function works as expected
    print(FOO);

    // Macro function not working
    int a = 3;
    printf("\nMacro Sum: %d", SUM(FOO, a));

    return 0;
}

I expect the output to be:

Sum: 3
Macro Sum: 6

However, I get the following error:

main.c:18:41: error: macro "SUM" requires 3 arguments, but only 2 given
     printf("\nMacro Sum: %d", SUM(FOO, a));

Upvotes: 6

Views: 6967

Answers (2)

rici
rici

Reputation: 241671

Macro arguments are not expanded when the macro call is parsed. After the macro call is parsed, each use of a macro parameter in the macro definition text is replaced with the macro-expanded argument, except for macro parameters used with the # or ## operations (stringify and token paste), which are replaced with the unexpanded text of the macro argument. Then the # and ## operations are performed, and then the entire macro body is scanned one more time.

The consequence is that SUM(FOO, a) is parsed aa having two arguments. Since the macro requires three, thatvwon't compile.

You can work around this, to some extent, by using one extra level of macro expansion:

#define CALL(macro, ...)  macro(__VA_ARGS__)

printf("\nMacro Sum: %d", CALL(SUM, FOO, a));

Now the use of the __VA_ARGS__ parameter (which happens to be a varargs parameter, although that makes absolutely no difference to the expansion order) will be expanded before the replacement text is rescanned, so FOO will be invoked with three arguments.


By the way, outputting a newline character at the beginning of an output line is a bad habit which will get you into trouble someday. Output lines should have a newline at the end of the line:

printf("Macro Sum: %d\n", CALL(SUM, FOO, a));

There is nothing wrong with also writing a blank line beforehand by putting a newline at the beginning as well, but regardless, you should almost always terminate outpur lines with the \n. Otherwise:

  1. The line might not be written immediately. Line-buffered output is not actually sent to the output device/file until a newline is sent.

  2. If the program is a console app and it terminates without properly closing stdout, you will find yourself typing the next shell command at rhe end if the last output line. This tends to confuse line-editing input libraries like readline.

Upvotes: 5

sg7
sg7

Reputation: 6298

Single macro argument would work:

#define SUM(X, Y, Z) X + Y + Z
#define FOO1 (1) 
#define FOO2 (2)

void print(int a, int b)
{
    printf("Sum: %d", a + b);
}

int main(void) 
{
    // Normal function works as expected
    print(FOO1,FOO2);  

    int a = 3;
    printf("\nMacro Sum: %d", SUM(FOO1, FOO2, a));

    return 0;
}

Output:

Sum: 3
Macro Sum: 6

Upvotes: 0

Related Questions