C宏内的宏扩展

时间:2019-06-18 22:17:58

标签: c-preprocessor

在测试C软件时,我想使用宏来生成函数调用。使用codewarrior 5.2(非常旧的)编译器-因为我没有选择,所以我不知道这是否是标准行为。

在macros.h

#define RUNTEST(i)              \
  testcase_index = i;             \
  __PREFIX__##_testCase_##i()

在test_foo.c

#include "macros.h"
#define __PREFIX__ foo

RUNTEST(10);

显然__PREFIX__没有展开,并且预处理程序会生成对__PREFIX___testcase_10()的调用,这当然会在链接时失败。 复制所有内容到同一文件似乎没有任何改变。

有简单的出路吗?

替代

我还尝试了#define __PREFIX__() foo来强制宏扩展。在这种情况下,它几乎有效,并且现在生成foo _testcase_10()(带有空格),当然不会编译。

1 个答案:

答案 0 :(得分:0)

我在这里已经完成了您问题的简化版本(未分配给测试用例索引):

.h

#define PASTER(x, y) x##_testCase_##y
#define EVAL(x, y) PASTER(x, y)
#define RUNTEST(i) EVAL(__PREFIX__, i)

.c

#define __PREFIX__ foo

// whatever

RUNTEST(1);

说明:

根据C标准:

  

6.10.3.1参数替换

     

在识别了调用类似函数的宏的参数之后,将进行参数替换。替换列表中的参数,除非在#或##预处理令牌之前或在##预处理令牌之后(请参见下文),否则在扩展其中包含的所有宏之后,将用相应的参数替换。在被替换之前,每个参数的预处理令牌都被完全替换为宏,就好像它们构成了其余的预处理文件一样;没有其他预处理令牌可用。

现在我们有了这个,我将逐步扩展RUNTEST(1)

EVAL(__PREFIX__, i)
PASTER(foo, 1)
foo##_testCase_##1
foo_testCase_1