Macro evaluation order [duplicate]

2020-06-08 10:03发布

Possible Duplicate:
# and ## in macros

why the output of second printf is f(1,2) what is the order in which macro is evaluated?

#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

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

output 12 
       f(1,2)

3条回答
小情绪 Triste *
2楼-- · 2020-06-08 10:34

An argument is macro-replaced before it is substituted into the replacement list, except where it appears as the operand of # (stringize) or ## (concatenate).

In your macro h, the parameter a is not an argument of one of those two operators, so the argument is macro-replaced and then substitued into the replacement list. That is, the argument f(1,2) is macro replaced to become 1##2, and then to 12, and then it is substituted into g(12), which is (again) macro-replaced to become "12".

When you invoke g directly, the parameter a is an argument of the # operator, so its argument is not macro-replaced before subsitution: f(1,2) is substituted directly into the replacement list, yielding "f(1,2)".

查看更多
疯言疯语
3楼-- · 2020-06-08 10:41

From http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan

Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them.

Meaning:

  • f concatenates its argument and so its argument is not expanded
  • h does not stringify or concatenate its argument and so its argument is expanded.
  • g stringifies its argument, and so its argument is not expanded

h(f(1,2)) -> g(12) -> "12"

g(f(1,2)) -> "f(1,2)"

查看更多
可以哭但决不认输i
4楼-- · 2020-06-08 10:43

I'm not sure order of evaluation is a meaningful term for C or C++ macros, because macro expansion happens at compile time

As to why the second output is f(1,2) is is because macros are textual substitution. When g(f(1,2)) is expanded, the argument of g is the sequence of tokens f(1,2) and that get stringified.

Think in terms of the C compiler. In the context of the second printf it reads a g token, recognize that it is a macro at lexing & parsing time then expand that macro invocation. The compiler is basically doing: if the current token is a macro name, then expand it when lexing your code. Macro expansion only happen when possible (so for a macro with arguments requires the  left parenthesis), and is done as soon as possible.

查看更多
登录 后发表回答