提问人:Pararera 提问时间:11/6/2023 最后编辑:Pararera 更新时间:11/6/2023 访问量:73
类似宏的功能,在体内有宏
Macro-like function with macros inside the body
问:
我正在尝试制作类似宏的函数,该函数将“创建”几行新宏。 ARM-GCC 预处理器对这种类似宏的函数不满意。如何在没有外部工具的情况下实现相同的功能的任何想法?
#define SML_DEBUG(_name) \
#if defined(DEBUG_##_name) \
#define _name##_LOG DEBUG_HANDLER \
#else \
#define _name##_LOG(...) \
#endif
任务是为用于打印调试内容的函数创建宏。
例如,
#define DEBUG
#define DEBUG_HANDLER log
#define DEBUG_TEST // Enable debug prints for test module
#define SML_DEBUG(TEST) // Should create test_LOG macro or its placeholder if DEBUG build is disabled
void foo(void)
{
TEST_LOG("Hello World\n"); // Will redirect to "log" function(defined by DEBUG_HANDLER)
}
错误是:
error: '#' is not followed by a macro parameter
182 | #define SML_DEBUG(_name) \
| ^
谢谢!
答:
2赞
Eric Postpischil
11/6/2023
#1
您得到的具体错误是因为在类似函数的宏(不是类似宏的函数)中应该用作字符串化运算符,如 ,根据 C 2018 6.10.3.2 1。由于您有 ,并且不是参数名称,因此编译器会抱怨。(这是一个约束段落,因此编译器需要抱怨它。#
#define MakeString(x) #x
#if
if
根据 C 2018 6.10.3.4 3,即使允许在宏替换列表中使用,处理宏生成的源代码也不会作为预处理器指令(例如 、 和 )进行处理。#
#if
#else
#endif
您可以有条件地定义宏,而不是尝试使用条件源代码定义宏:
#if defined DEBUG_TEST
#define _TEST_LOG DEBUG_HANDLER
#else
#define _TEST_LOG(...)
#endif
这意味着您需要为要启用/禁用日志记录的每个模块重复这些行,但这就是源代码编辑器和脚本语言的用途。并非所有事情都应该在 C 预处理器中完成。
评论
0赞
Pararera
11/6/2023
谢谢你的解释。我的类似函数的宏应该扩展到您编写的示例。只是为了更容易将调试日志记录添加到模块/驱动程序,因为我计划为多个级别(错误、警告、信息、详细)添加选项,所以复制粘贴似乎很讨厌。似乎我必须坚持 c/p 并重命名:|SML_DEBUG(TEST)
0赞
Pararera
11/6/2023
添加。这是结果
评论
#if
#else
#endif
#
#define MakeString(x) #x
#if
if