C++ CPP宏:给出实例化/调用次数的计数器
我想要一个C预处理器宏,它知道到目前为止该宏的实例化/宏调用的数量。 例如: 应该打印C++ CPP宏:给出实例化/调用次数的计数器,c++,c-preprocessor,C++,C Preprocessor,我想要一个C预处理器宏,它知道到目前为止该宏的实例化/宏调用的数量。 例如: 应该打印 0 1 这样的事情可能吗 请注意,不足以将其转发给下面建议的功能。 它应在以下背景下发挥作用: // global variable std::vector<bool> calls_hit; #define OTHER_MACRO() \ { \ const int counter = MACRO(); \ calls_hit.resize(std::max(calls_hit
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; \
}
//全局变量
std::向量调用\u hit;
#定义其他_宏()\
{ \
常量int计数器=宏()\
调用_hit.resize(std::max(调用_hit.size(),计数器))\
调用\u hit[计数器]=真\
}
为什么这必须是宏?无论如何,您可以在宏中使用静态计数器包装函数:
int count_calls() {
static count = 0;
return count++;
}
#define MACRO() count_calls()
你怎么了
// 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;
}
//全局变量
std::向量调用\u hit;
内联无效函数,因为此函数不是
{
静态无符号整数命中=0;
常量int计数器=命中++;
调用_hit.resize(std::max(调用_hit.size(),计数器));
调用\u hit[计数器]=真;
}
我碰巧有一个与\uuuuu COUNTER\uuuu
类似的解决方案(在使用中),但不限于单个计数器-您可以根据需要定义多个计数器
这一个使用特定于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扩展到类似于从\uuuuuuuuuuuuuuuuuuuu
信息生成的部分(“.rodata.line01234”)
以下是对其工作原理的解释:
\uuuuuuuuuuuuuuuuuuuuu值推送到LSEG宏指定的内存段的代码,以及2)调用getpos(\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu行
)函数的代码,该函数返回写入给定行的调用次数
\uuuu LINE\uuu
值都是按使用顺序排列的\uuuuuuuu LINE\uuuuu
)函数扫描内存段,并返回写入给定行的调用数希望这能有所帮助。@Andy:那么当然,计数也会增加。不,这不起作用。我想知道编译时的调用数。@Manuel:如果你想知道编译时的调用数,你必须使用类似于
\uuuuu COUNTER\uuuu
的宏来包装对目标函数的调用,但是,这意味着你不能使用\uuu COUNTER\uuuu
来处理任何其他事情…@Manuel:不能使用宏。模板元编程可能会有所帮助,但您需要提供更多细节。特别是,我的解决方案仍然适用于您在问题中发布的新代码;没有编译时间知识。删除了<代码> C++ >代码>标签,因为这似乎不是C++。把<代码> C++ > /CODE>标签重新加入,因为现在使用的是代码> STD::vector < /代码>。代码>LSEG的定义来自哪里?快速的谷歌搜索什么也没发现。我省略了LSEG的定义,因为该定义本身是一个复杂的代码来解释。我目前在编辑时遇到了一些问题,比如定义STR(s)#s#定义STR(s)STR(s)#定义EVAL(func,…)func(VA#ARGS)#定义LSEG(n)部分(STR(.rodata.line##n))#定义LSEG EVAL(LSEG,ALIGN#数字(line))而ALIGN_DIGIT的定义太长,无法包含在这里,因为我通过定义#define ALIGN_DIGIT_1 00001#define ALIGN_DIGIT_2 00002……将其拼凑起来#定义ALIGN_DIGIT_65536 65536这是我找到的唯一方法,因为GNU ld只按非数字字典顺序对节进行排序。注意:我只是为了好玩才这么做的。像这样的宏不应该出现在现实世界的代码中。。。
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;
}