Вопрос

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top