用于选择性替换的C宏技巧

时间:2012-08-01 15:27:48

标签: c macros c-preprocessor

是否有一个宏技巧来重命名函数调用而不影响函数定义,特别是对于gcc / cpp:

#define get_resolution __mock_get_resolution

上面的宏会更改所有地方,但我只是希望这对函数调用get_resolution();生效,而不会影响定义void get_resolution()

void get_resolution()
{
}

void display()
{
    get_resolution();
}

3 个答案:

答案 0 :(得分:3)

作为特定于gcc的解决方案,

 The `alias' attribute causes the declaration to be emitted as an
 alias for another symbol, which must be specified.  For instance,

      void __f () { /* Do something. */; }
      void f () __attribute__ ((weak, alias ("__f")));

答案 1 :(得分:2)

不,C预处理器没有C程序结构的语义知识,只看到文本标记。

一个选项是在定义之前#undef宏,然后再重新定义它,但这很麻烦。另一种选择是将宏添加到你想要模拟的每个函数的定义中:

#if DO_MOCKING
#define IMPLEMENT_MOCKABLE_FUNCTION(funcname) _real_ ## funcname
#define get_resolution _mock_get_resolution
#else
#define IMPLEMENT_MOCKABLE_FUNCTION(funcname) funcname
#endif

...

void IMPLEMENT_MOCKABLE_FUNCTION(get_resolution)()
{
    ...
}

另请注意,以两个下划线开头的标识符以及以下划线后跟大写字母开头的标识符由实现(即编译器和标准库)保留。所以我在上面的例子中重命名了标识符,使用单个下划线和小写字母。

答案 2 :(得分:0)

你可以这样做:

#define get_resolution __mock_get_resolution

全局可访问(如您总是包含的标题等),然后执行此操作:

#undef get_resolution
void get_resolution()
{
}
#define get_resolution __mock_get_resolution

void display()
{
    get_resolution();
}

丑陋的黑客攻击,但它会让你不得不写一个sed(1)脚本。

测试用例如下:

$ gcc -o test test.c
$ ./test
__mock_up
$ cat test.c        
#include <stdio.h>

#define get_resolution __mock_up

int
__mock_up()
{
        printf("__mock_up\n");  
}

#undef get_resolution
int 
get_resolution()
{

}
#define get_resolution __mock_up

int main()
{
       get_resolution();
       return 0;
}
$