- 论坛徽章:
- 0
|
根据我的经验:
C的宏处理完全是词法分析的范畴,gcc调用预处理器cpp将所有包含文件和源文件进行预处理之后生成一个.i的中间文件,再将这个中间文件传递给cc1进行编译.
可以使用-v选项观察gcc编译过程.
另外,预处理并不仅仅处理宏展开.
关于宏的展开可以参考gcc源代码:
下面的代码来自gcc-1.35的cccp.c
- /* Structure allocated for every #define. For a simple replacement
- such as
- #define foo bar ,
- nargs = -1, the `pattern' list is null, and the expansion is just
- the replacement text. Nargs = 0 means a functionlike macro with no args,
- e.g.,
- #define getchar() getc (stdin) .
- When there are args, the expansion is the replacement text with the
- args squashed out, and the reflist is a list describing how to
- build the output from the input: e.g., "3 chars, then the 1st arg,
- then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
- The chars here come from the expansion. Whatever is left of the
- expansion after the last arg-occurrence is copied after that arg.
- Note that the reflist can be arbitrarily long---
- its length depends on the number of times the arguments appear in
- the replacement text, not how many args there are. Example:
- #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
- pattern list
- { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
- where (x, y) means (nchars, argno). */
- /* 对每个#define 分配的结构. 对于简单的替换例如:
- #define foo bar ,
- nargs = -1 , `样式' 列表(见结构体定义中的pattern list) 为空,
- expansion ( 见结构体中的expansion 定义) 仅仅是替换文本.
- Nargs=0 意味着一个不带参数的函数类似的宏定义, 例如:
- #define getchar() getc(stdin).
- 当存在参数的时候, expansion 是不带任何参数的替换文本,
- 并且reflist 是一个描述如何从输入构建输出的列表:
- 例如: " 三个字符, 然后第一个参数, 之后久个字符,
- 之后第三个参数, 之后零个字符, 之后第二个参数."
- 这里的字符来自expansion.
- Whatever is left of the
- expansion after the last arg-occurrence is copied after that arg.
- 注意: reflist 可以是任意长度:
- 它的长度依赖于参数在替换文本中出现的次数,
- 而不是到底有多少参数, 例如:
- #define f(x) x+x+x+x+x+x+x 将会有替换文本"++++++" 和样式列表:
- { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
- 这里的(x,y) 的意义是(nchars,argno) 即(字符数, 参数序号)
- */
- typedef struct definition DEFINITION;
- struct definition {
- int nargs;
- int length; /* length of expansion string */ /* expansion string 的长度*/
- U_CHAR *expansion; /* expansion string*/
- struct reflist {
- struct reflist *next;
- char stringify; /* nonzero if this arg was preceded by a # operator. */
- /* 非零, 如果这个参数之前有# 操作符*/
- char raw_before; /* Nonzero if a ## operator before arg. */ /* 非零如果一个## 在这个操作符前*/
- char raw_after; /* Nonzero if a ## operator after arg. */ /* 非零如果一个## 在这个操作符后*/
- int nchars; /* Number of literal chars to copy before this arg occurrence. */
- /* 在这个参数出现之前需要复制的字符数*/
- int argno; /* Number of arg to substitute (origin-0) */
- /* 需要替换的参数的序号(初始为0) */
- } *pattern; /* pattern list */ /* 样式列表 */
复制代码
[ 本帖最后由 crspo 于 2006-2-22 19:15 编辑 ] |
|