在我的项目中,我有很多文件,我想用C ++宏来管理调试。对于每个文件,我想使用自己的开关来启用或禁用调试并调整调试级别。所以基本上有共享文件和设置:
这是共享文件debug.h的外观:
#define DEBUG_LEVEL_LOG -1
#define DEBUG_LEVEL_NONE 0
#define DEBUG_LEVEL_ERROR 1
#define DEBUG_LEVEL_WARNING 2
#define DEBUG_LEVEL_INFO 3
#define DEBUG_LEVEL_DEBUG 4
#define DEBUG_LEVEL_TRACE 5
#ifndef ON
#define ON 1
#endif
#ifndef OFF
#define OFF 0
#endif
// setings for component "wireless"
#define WIRELESS_DEBUGGING ON
#define WIRELESS_DEBUGGING_LEVEL DEBUG_LEVEL_ERROR
// settings for another components
...
在我想用这个设置调试的每个文件中,我需要定义另一堆宏。例如文件“wireless.h”
#ifndef WIRELESS_DEBUGGING
#define WIRELESS_DEBUGGING_LEVEL DEBUG_LEVEL_NONE
#endif
#if WIRELESS_DEBUGGING
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_LOG
#define WIRELESS_LOG(...); Logger::log(__VA_ARGS__);
#else
#define WIRELESS_LOG(...); {}
#endif
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_ERROR
#define WIRELESS_ERROR(...); Logger::error(__VA_ARGS__);
#else
#define WIRELESS_ERROR(...); {}
#endif
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_WARNING
#define WIRELESS_WARNING(...); Logger::warning(__VA_ARGS__);
#else
#define WIRELESS_WARNING(...); {}
#endif
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_INFO
#define WIRELESS_INFO(...); Logger::info(__VA_ARGS__);
#else
#define WIRELESS_INFO(...); {}
#endif
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_DEBUG
#define WIRELESS_DEBUG(...); Logger::debug(__VA_ARGS__);
#else
#define WIRELESS_DEBUG(...); {}
#endif
#if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_TRACE
#define WIRELESS_TRACE(...); Logger::trace(__VA_ARGS__);
#else
#define WIRELESS_TRACE(...); {}
#endif
#else
#define WIRELESS_LOG(...); {}
#define WIRELESS_ERROR(...); {}
#define WIRELESS_WARNING(...); {}
#define WIRELESS_INFO(...); {}
#define WIRELESS_DEBUG(...); {}
#define WIRELESS_TRACE(...); {}
#endif
当我想调试给定的组件时,我只是使用这样的东西(在wireless.cpp中)
WIRELESS_TRACE("wireless: hello world\n");
... etc ...
到目前为止,它正在发挥作用。这里有一个问题:我不想在我只使用不同前缀的每个组件中使用类似于文件“wireless.h”中定义的“本地”一堆定义。而不是这个我想要一些看起来类似于这个
的“超级宏”REGISTER_DEBUG(WIRELESS);
有没有办法如何使用一些串联和多行宏来实现这一点?我发现禁止在#define
内使用#define
。
答案 0 :(得分:0)
我不完全确定你想要什么,所以如果这不合适,请告诉我,我会删除。
使用constructor.py
可以在预处理器中连接令牌。例如,请参阅https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html
答案 1 :(得分:0)
这有点笨拙,但应该做的诀窍:
#define DEBUG_LEVEL_LOG -1
#define DEBUG_LEVEL_NONE 0
#define DEBUG_LEVEL_ERROR 1
#define DEBUG_LEVEL_WARNING 2
#define DEBUG_LEVEL_INFO 3
#define DEBUG_LEVEL_DEBUG 4
#define DEBUG_LEVEL_TRACE 5
#define TRACE(a,...) _TRACE(a,__VA_ARGS__)
#define _TRACE(a,...) __TRACE_##a(__VA_ARGS__)
#define __TRACE_5(...) do{Logger::trace(__VA_ARGS__);}while(0)
这是笨拙:您还需要定义__TRACE_4
,__TRACE_3
等等为空。然后你需要为Debug定义相同的东西:
#define __DEBUG_4(...) do{Logger::debug(__VA_ARGS__);}while(0)
但最后,在您定义了无线日志级别之后:
#define WIRELESS_LEVEL 5
你可以像这样调用宏:
TRACE(WIRELESS_LEVEL,"wireless: hello world\n");
修改的 或者(这可能更干净):
#define __PRINT_55(...) do{Logger::trace(__VA_ARGS__);}while(0)
#define __PRINT_44(...) do{Logger::debug(__VA_ARGS__);}while(0)
// etc...
// Also need to define what you need to be not printed:
#define __PRINT_01(...)
// etc...
#define PRINT(a,b,...) _PRINT(a,b,__VA_ARGS__)
#define _PRINT(a,b,...) __PRINT_##a##b(__VA_ARGS__)
现在你可以这样调用你的函数:
PRINT(DEBUG_LEVEL_TRACE, WIRELESS_LEVEL, "Hello world\n");
答案 2 :(得分:0)
您可以通过从宏切换到内联函数来实现目标。像这样:
// debug.h
enum DebugLevel {
DEBUG_LEVEL_LOG = -1,
DEBUG_LEVEL_NONE = 0,
DEBUG_LEVEL_ERROR = 1,
DEBUG_LEVEL_WARNING = 2,
DEBUG_LEVEL_INFO = 3,
DEBUG_LEVEL_DEBUG = 4,
DEBUG_LEVEL_TRACE = 5
};
// settings for component "wireless"
constexpr bool WIRELESS_DEBUGGING = true;
constexpr DebugLevel WIRELESS_DEBUGGING_LEVEL = DEBUG_LEVEL_ERROR;
#define REGISTER_DEBUG_FUNC(topic, level, func) \
template <typename... Args> \
inline void topic##_##level(Args&& ... args) { \
if ( topic##_DEBUGGING && topic##_DEBUGGING_LEVEL >= DEBUG_LEVEL_##level ) \
Logger::func(std::forward<Args>(args)...); \
}
#define REGISTER_DEBUG(topic) \
REGISTER_DEBUG_FUNC(topic, LOG, log) \
REGISTER_DEBUG_FUNC(topic, ERROR, error) \
REGISTER_DEBUG_FUNC(topic, WARNING, warning) \
REGISTER_DEBUG_FUNC(topic, INFO, info) \
REGISTER_DEBUG_FUNC(topic, DEBUG, debug) \
REGISTER_DEBUG_FUNC(topic, TRACE, trace)
// wireless.h
REGISTER_DEBUG(WIRELESS)