Macro evaluation order [duplicate]

半腔热情 提交于 2019-12-05 15:56:34

问题


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)

回答1:


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)"




回答2:


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:


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.



来源:https://stackoverflow.com/questions/8754593/macro-evaluation-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!