所有对框架的各种调用都是通过宏完成的,例如:
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
宏。问题:
- 是否能够创建这样一个帮助宏?
- 有更好的方法可以实现我想要的吗?
在发布此问题之前,我尝试了自己解决问题,下面是我写的代码,可能有助于说明我当时的思路。
#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;
}
#define
macro for debug printing中的讨论。虽然该讨论是关于调试代码的,但很容易适应于性能分析代码或其他特殊情况。个人而言,我可能会选择一个#define PROFILE_START(component, msg) …
的变体,其中 component 可以用于条件等。也许是#define PROFILE_START(component, msg) (profile_ ## component ? currentProfiler().start(msg) : (void)0)
或类似的定义。这假设你已经定义了profile_BAR
等宏(?)。 - Jonathan Leffler