我希望有一个 C 预处理器宏,它知道到目前为止该宏的实例化/宏调用的数量。 例如:
int main() {
printf("%d\n", MACRO());
printf("%d\n", MACRO());
}
应打印
0
1
这样的事情可能吗?
请注意,不足以将其转发给下面建议的功能。 它应该在以下环境中起作用:
// global variable
std::vector<bool> calls_hit;
#define OTHER_MACRO() \
{ \
const int counter = MACRO(); \
calls_hit.resize(std::max(calls_hit.size(), counter)); \
calls_hit[counter] = true; \
}
答案 0 :(得分:5)
为什么这必须是一个宏?无论如何,您可以在宏中使用静态计数器包装函数:
int count_calls() {
static count = 0;
return count++;
}
#define MACRO() count_calls()
答案 1 :(得分:2)
我碰巧有一个与__COUNTER__
类似(使用中)的解决方案,但不仅限于单个计数器 - 您可以根据需要定义许多计数器。
这个使用gcc特有的功能,但应该能够在其他工具链中做类似的事情。
static int getpos(int lineno); // forward declaration
#define MY_COUNTER ({ \
static const int mark __attribute__((LSEG,used)) = __LINE__; \
getpos(__LINE__); \
})
static int __attribute__((noinline)) getpos(int lineno) {
static const int mark __attribute__((LSEG,used)) = __LINE__;
const int *p = &mark;
int i;
for (i = 0; *p++ != lineno; i++);
return i;
}
在上面的代码中,LSEG扩展为类似于__LINE__
信息生成的section(“。rodata.line01234”)。
以下是对其工作原理的阐述:
__LINE__
值推送到LSEG宏指定的内存段的代码,以及2)调用getpos(__LINE__
)的代码function,返回写入给定行的调用数。__LINE__
值都按照它们的使用顺序排列。__LINE__
)函数扫描内存段,并返回写入给定行的调用数。希望这有帮助。
答案 2 :(得分:1)
有什么问题
// global variable
std::vector<bool> calls_hit;
inline void a_function_since_this_is_not_C_after_all()
{
static unsigned int hits = 0;
const int counter = hits++;
calls_hit.resize(std::max(calls_hit.size(), counter));
calls_hit[counter] = true;
}