当前位置:Linux教程 - Linux文化 - 如何处理C的预处理?

如何处理C的预处理?


>>> 此贴的回复 >> 语法分析和词法分析 有专门的工具.LEX,YACC. 你可以找相关的资料看一下.

至于此问题.为何非要预处理 而不封装成函数?

>>> 此贴的回复 >> >> 函数宏的处理比较麻烦,因为它有语法.如果作为语法处理 预处理就是简单的宏替换, #指令解析等, 处理完毕的结果才作为词法分析的输入文件, 完全不涉及词法、语法分析的操作啊。

>>> 此贴的回复 >> 根据我的经验: C的宏处理完全是词法分析的范畴,gcc调用预处理器cpp将所有包含文件和源文件进行预处理之后生成一个.i的中间文件,再将这个中间文件传递给cc1进行编译. 可以使用-v选项观察gcc编译过程. 另外,预处理并不仅仅处理宏展开. 关于宏的展开可以参考gcc源代码: 下面的代码来自gcc-1.35的cccp.c

CODE:[Copy to clipboard]/* 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 */ /* 样式列表 */