用C宏替换函数/变量名称的一部分

问题描述 投票:2回答:1

我正在编写一些代码,我想多次使用,但功能和变量名称略有不同。我想用宏替换部分函数和变量名。 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
c replace macros c-preprocessor
1个回答
1
投票

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

如果你听说预处理器做了纯文本替换,那就太过简单了。它以令牌运行,最好始终牢记在心。

所以你需要的是一种机制,通过这种机制,预处理器接受_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]*),用于任何用途。自己使用它们会让您对未定义的行为保持开放。通常,尽量避免在标识符中使用下划线,除非您已经了解了保留标识符的所有规则。

© www.soinside.com 2019 - 2024. All rights reserved.