首页 > 解决方案 > C 宏仅更改函数调用而不更改函数定义

问题描述

我有一个非常相似的问题:Macro and function with same name

我想要一个宏只改变函数调用而不是函数本身

#define original_function(a, b) replace_function(a, b)

uint64_t replace_function(int a, int b) {
    // some functionality
}

uint64_t original_function(int a, int b) {
    // some functionality
}

uint64_t main(uint64_t argc, uint64_t* argv) {
    original_function(10, 20);
}

这将导致更改原始函数定义

#define original_function(a, b) replace_function(a, b)

uint64_t replace_function(int a, int b) {
    // some functionality
}

uint64_t replace_function(int a, int b) {
    // some functionality
}

uint64_t main(uint64_t argc, uint64_t* argv) {
    original_function(10, 20);
}

我不能这样做(这是链接问题中的答案)

uint64_t (original_function)(int a, int b) {
    // some functionality
}

//...

我不能把定义放在函数后面

uint64_t original_function(int a, int b) {
    // some functionality
}

#define original_function(a, b) replace_function(a, b)

// ...

是否可以在宏中定义仅更改函数调用而不更改函数定义?或者我可以以某种方式定义一个宏来仅重命名原始函数(而不是调用),这样它就不会受到影响?

编辑: 之后我只能更改宏而不是代码...

标签: cmacrosc-preprocessor

解决方案


您可以使用 C 预处理器“模式匹配”定义所在的行。要以有用的方式执行此操作,首先您需要一个间接SECOND宏:

#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(A,B,...) B

...然后有一个间接的很有用GLUE

#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B

...最后,original_function当且仅当它出现在特定行上时,“选择性地蓝色油漆”到自身上(这种方法需要弄清楚它在哪一行,但我建议不要对这个奇怪的请求挑剔):

#define original_function(a,b) \
   SECOND(GLUE(EXCEPT_FOR_LINE_,__LINE__),replace_function)(a,b)

因此,鉴于未定义第一个构造的标记,此宏将original_function使用两个参数扩展。replace_function但是,如果定义了第一个标记,则标记首先展开,然后选择第二个参数。这意味着,你可以这样做:

#define EXCEPT_FOR_LINE_6 ,original_function

...如果 original_function 实际上是在第 6 行定义的(而不是在第 6 行调用),那么最终扩展看起来就像第 6 行的原始...;在所有其他行上,它将生成对replace_function.

此示例在您的代码中使用此技术。作为奖励,本示例中上述所有宏都是在命令行上定义的(根据您在评论中反映的预期用途)。


推荐阅读