类似宏的函数,体内有宏

问题描述 投票:0回答:1

我正在尝试创建类似宏的函数,它将“创建”几行新宏。 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) \
      |                        ^

谢谢!

c c-preprocessor
1个回答
0
投票

您收到的具体错误是因为类函数宏(不是类宏函数)中的

#
应该用作字符串化运算符,如
#define MakeString(x) #x
中所示,根据 C 2018 6.10.3.2 1。由于您有
#if
,并且
if
不是参数名称,因此编译器会抱怨。 (这是一个约束段落,因此编译器需要对此进行抱怨。)

即使在宏替换列表中允许使用

#
,处理宏所产生的源代码也不会被处理为预处理器指令(例如
#if
#else
#endif
),即使它类似于一个,根据 C 2018 6.10.3.4 3.

您可以有条件地定义宏,而不是尝试使用条件源代码定义宏:

#if defined DEBUG_TEST
    #define _TEST_LOG DEBUG_HANDLER
#else
    #define _TEST_LOG(...)
#endif

这意味着您需要为要启用/禁用日志记录的每个模块重复这些行,但这就是源代码编辑器和脚本语言的用途。并非所有事情都应该在 C 预处理器中完成。

© www.soinside.com 2019 - 2024. All rights reserved.