c - 用 C 宏替换部分函数/变量名

标签 c replace macros c-preprocessor

我正在编写一些我想多次使用的代码,函数名和变量名略有不同。我想用宏替换部分函数和变量名。 gcc filename.c -E 表明没有进行替换。我该如何纠正这个问题?

这是文件中的一些代码,在替换之前:

#define    _CLASS       Object
#define    POOLLEVEL1   1024
#define    POOLLEVEL2   1024


typedef struct {
    int Self;
    int Prev;
    int Next;
    int In_Use;

//----data----//

//----function pointers----//

} Object;

_CLASS* _CLASS_Pool[POOLLEVEL1] = { 0 };
//Note on POOLLEVEL1, POOLLEVEL2: _CLASS_Pool[] is an array of pointers to arrays of type _CLASS. The number of objects in these arrays is LEVEL2, the maximum number of arrays of type object is LEVEL1; The arrays of type object are allocated when needed.

int _CLASS_Available_Head = -1;
int _CLASS_Available_Tail = -1;
//Start and finish of list of available objects in pool.

// More follows

最佳答案

预处理器对标记进行操作。当谈到标识符时,_CLASS 是一个标记,而 _CLASS_Pool 则完全是另一个标记,因为它们是不同的标识符。预处理器不会在解析标识符的过程中停下来检查它的一部分是否是另一个标识符。不,它会在识别标识符之前吞噬所有 _CLASS_Pool

如果您听说过预处理器进行纯文本替换,那是一种严重的过度简化。它在 token 上运行,最好始终牢记这一点。

因此,您需要一种机制,预处理器可以通过该机制接受 _CLASS 作为标记、展开它,然后将其粘贴到另一个标记。幸运的是,这些机制已经存在。可以这样写:

#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a ## b

像这样使用:

_CLASS* CONCAT(_CLASS, _Pool)[POOLLEVEL1] = { 0 };

int CONCAT(_CLASS, _Available_Head) = -1;

/* and so forth */

第一个 CONCAT 接受您的参数,并将它们转发给另一个函数,如宏。转发它们允许任何中间扩展,如 _CLASS -> Object。不是类对象宏的标记保持不变。 CONCAT_ 然后简单地应用内置的标记粘贴运算符。您可以检查结果并进一步调整它。


顺便说一句,C 标准保留所有以下划线开头,后跟大写字母 (_[A-Z][0-9a-zA-Z]*) 的标识符,实现,用于任何用途。自己使用它们会使您对未定义的行为敞开大门。通常,尽量避免在标识符中使用前导下划线,除非您熟记保留标识符的所有规则。

关于c - 用 C 宏替换部分函数/变量名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55701815/

相关文章:

c - 删除逗号之间的白色字符,但不删除逗号内的内容

c - C 中的欧拉项目 8

javascript - 正则表达式替换与任何字符匹配的所有内容

php - 从字符串中删除美元符号

C++如何压缩花哨的for循环

c - boost::bind 在 C 中等效?

c++ - 枚举 C++ 中的宏

c - AT 命令 ESP8266 01 : AT+CIPSTART: How to fix response Link type Error/Can't connect with TCP

c - 在线练习技术面试,我错过了什么?

c - 如何在 C 中用空字符替换空格和制表符?