C宏仅更改函数调用而不更改函数定义
C macro to only change function calls and not function definitions
我有一个非常相似的问题: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)
// ...
是否可以在宏中定义为仅更改函数调用而不更改函数定义?
或者我可以以某种方式定义一个宏来仅重命名原始函数(而不是调用),这样它就不会受到影响吗?
编辑:
之后我只能改宏,不能改代码...
您可以 "pattern match" 使用 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
...最后,当且仅当它出现在特定行上时,"selectively blue paint" original_function
才会出现(这种方法需要弄清楚它在哪一行,但我建议不要对这个奇怪的要求很挑剔):
#define original_function(a,b) \
SECOND(GLUE(EXCEPT_FOR_LINE_,__LINE__),replace_function)(a,b)
所以这个宏将扩展 original_function
带有两个带有 replace_function
的参数,假设第一个构造的标记未定义。但是,如果定义了第一个标记,则标记首先扩展,然后选择 that 的第二个参数。这意味着,您可以这样做:
#define EXCEPT_FOR_LINE_6 ,original_function
...如果 original_function 实际上是在第 6 行定义的(而不是在第 6 行调用的),那么最终的扩展看起来像原始的...在第 6 行;在所有其他线路上,它将生成对 replace_function
.
的调用
This example 在您的代码中使用了这种技术。作为奖励,此示例中上面的所有宏都是在命令行上定义的(根据您在评论中反映的预期用途)。
我有一个非常相似的问题: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)
// ...
是否可以在宏中定义为仅更改函数调用而不更改函数定义? 或者我可以以某种方式定义一个宏来仅重命名原始函数(而不是调用),这样它就不会受到影响吗?
编辑: 之后我只能改宏,不能改代码...
您可以 "pattern match" 使用 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
...最后,当且仅当它出现在特定行上时,"selectively blue paint" original_function
才会出现(这种方法需要弄清楚它在哪一行,但我建议不要对这个奇怪的要求很挑剔):
#define original_function(a,b) \
SECOND(GLUE(EXCEPT_FOR_LINE_,__LINE__),replace_function)(a,b)
所以这个宏将扩展 original_function
带有两个带有 replace_function
的参数,假设第一个构造的标记未定义。但是,如果定义了第一个标记,则标记首先扩展,然后选择 that 的第二个参数。这意味着,您可以这样做:
#define EXCEPT_FOR_LINE_6 ,original_function
...如果 original_function 实际上是在第 6 行定义的(而不是在第 6 行调用的),那么最终的扩展看起来像原始的...在第 6 行;在所有其他线路上,它将生成对 replace_function
.
This example 在您的代码中使用了这种技术。作为奖励,此示例中上面的所有宏都是在命令行上定义的(根据您在评论中反映的预期用途)。