【发布时间】:2017-10-26 13:42:09
【问题描述】:
我们有一个分析框架,可以在编译时启用和禁用。
对框架的所有各种调用都是通过宏完成的,例如:
PROFILE_START(msg)
PROFILE_END(msg)
然后,宏在启用分析时解析为实际的分析器调用,而在禁用时解析为任何内容
#ifdef PROFILING_ENABLED
# define PROFILE_START(msg) currentProfiler().start(msg)
# define PROFILE_END(msg) currentProfiler().end(msg)
#else
# define PROFILE_START(msg)
# define PROFILE_END(msg)
#endif
我们的框架中有各种不同的组件,我想在每个组件中启用分析。
我希望能够有选择地在每个组件中启用分析。
我的想法是在所有探查器宏前面加上组件的名称,例如:
FOO_PROFILE_START(msg)
FOO_PROFILE_END(msg)
BAR_PROFILE_START(msg)
BAR_PROFILE_END(msg)
我可以手动创建
#ifdef ENABLE_FOO_PROFILING
# define FOO_PROFILE_START(msg) PROFILE_START(msg)
# define FOO_PROFILE_END(msg) PROFILE_END(msg)
#else
# define FOO_PROFILE_START(msg)
# define FOO_PROFILE_END(msg)
#endif
#ifdef ENABLE_BAR_PROFILING
# define BAR_PROFILE_START(msg) PROFILE_START(msg)
# define BAR_PROFILE_END(msg) PROFILE_END(msg)
#else
# define BAR_PROFILE_START(msg)
# define BAR_PROFILE_END(msg)
#endif
但是,这既乏味又容易出错。
每当向分析框架添加新功能时,我都必须找到所有组件特定的宏并为每个宏添加一个新宏。
我正在寻找的是一种自动生成以组件为前缀的宏的方法。
#ifdef ENABLE_FOO_PROFILING
ADD_PREFIX_TO_ENABLED_PROFILING_MACROS(FOO)
#else
ADD_PREFIX_TO_DISABLED_PROFILING_MACROS(FOO)
#endif
上述的最终结果将是创建所有我会手动完成的FOO_PROFILE_XXX 宏。
问题:
- 这样的辅助宏可能吗?
- 有没有更好的方法来实现我的目标?
如有必要,我很乐意使用 BOOST_PP。
在发布这个问题之前,我尝试自己弄清楚这一点,我想出的代码如下,这可能有助于显示我正在走的路
#include <stdio.h>
#define PROFILE_START(msg) printf("start(%s)\n", msg);
#define PROFILE_END(msg) printf("end(%s)\n", msg);
#define ENABLE(prefix) \
#define prefix ## _PROFILE_START PROFILE_START \
#define prefix ## _PROFILE_END PROFILE_END
#define DISABLE(prefix) \
#define prefix ## _PROFILE_START \
#define prefix ## _PROFILE_END
#define ENABLE_FOO
#ifdef ENABLE_FOO
ENABLE(FOO)
#else
DISABLE(FOO)
#endif
#ifdef ENABLE_BAR
ENABLE(BAR)
#else
DISABLE(BAR)
#endif
int main()
{
FOO_PROFILE_START("foo");
FOO_PROFILE_END("foo");
BAR_PROFILE_START("bar");
BAR_PROFILE_END("bar");
return 0;
}
【问题讨论】:
-
不要垃圾标签!这显然不是 C。
-
@Olaf 它是关于 C 预处理器的,所以在 C 中工作的任何东西都可以在这里工作。如果您觉得这是垃圾邮件,请道歉,那不是我的意图
-
@Olaf 对我来说,不能在宏中创建宏并不明显,我不确定你指的是什么?我也不确定你说我们不是咨询网站是什么意思
-
@Olaf 将代码更新为 C,以更好地反映我的问题
-
看C
#definemacro for debug printing的讨论。尽管这是关于调试代码,但它很容易适应分析代码或任何其他特殊情况。就个人而言,我可能会在#define PROFILE_START(component, msg) …上使用一个变体,该组件可以在条件等条件下使用。也许#define PROFILE_START(component, msg) (profile_ ## component ? currentProfiler().start(msg) : (void)0)或类似的。假设您已定义profile_BAR等(作为宏?)。
标签: c++ macros c-preprocessor boost-preprocessor