简体   繁体   中英

Macro within macro does not work

I came across one more piece of code that is even more confusing..

#include "stdio.h"

#define f(a,b) a##b

#define g(a) #a

#define h(a) g(a)

int main(void)
{
    printf("%s\n",h(f(1,2)));
    printf("%s\n",g(1));
    printf("%s\n",g(f(1,2)));
    return 0;
}

output is

12

1

f(1,2)

My assumption was 1) first f(1,2) is replaced by 12 , because of macro f(a,b) concantenates its arguments 2) then g(a) macro replaces 1 by a string literal "1" 3) the output should be 1

But why is g(f(1,2)) not getting substituted to 12 . I'm sure i'm missing something here. Can someone explain me this program ?

Macro replacement occurs from the outside in. (Strictly speaking, the preprocessor is required to behave as though it replaces macros one at a time, starting from the beginning of the file and restarting after each replacement.)

The standard (C99 §6.10.3.2/2) says

If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument.

Since # is present in the replacement list for the macro g , the argument f(1,2) is converted to a string immediately, and the result is "f(1,2)" .

On the other hand, in h(f(1,2)) , since the replacement list doesn't contain # , §6.10.3.1/1 applies,

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.

and the argument f(1, 2) is macro expanded to give 12 , so the result is g(12) which then becomes "12" when the file is "re-scanned".

Macros can't expand into preprocessing directives. From C99 6.10.3.4/3 "Rescanning and further replacement":

The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one,

Source: https://stackoverflow.com/a/2429368/2591612

But you can call f(a,b) from g like you did with h . f(a,b) is interpreted as a string literal as @Red Alert states.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM