gpt4 book ai didi

C 预处理器 - 根据另一个宏定义不同的宏

转载 作者:太空宇宙 更新时间:2023-11-04 03:21:22 26 4
gpt4 key购买 nike

我有一个调试设置,您可以在 makefile 中设置各种调试标志,然后在我们拥有的每个源文件中:

#ifdef DEBUG_FLAG
# define DEBUGGING(...) Something(__VA_ARGS__)
#else
# define DEBUGGING(...) do {} while(0)
#endif

我想让源文件更简洁一些:

#define DEBUGGING(...) DEBUG_HELP( DEBUG_FLAG, Something(__VA_ARGS__) )

其中 DEBUG_HELP 是在 header 中定义的,具有相同的最终结果,即使用 DEBUGGING 宏将导致调用 Something,仅当 DEBUG_FLAG 被定义为非零时。如果 DEBUG_FLAG 根本没有定义,那么代码应该仍然可以编译,只是不会调用 Something

这可能吗?

到目前为止,我的尝试还没有找到一种方法,在根本未定义 DEBUG_FLAG 的情况下不会出现编译错误。

最佳答案

盗用 Nominal Animal 对类似问题的回答,Test if preprocessor symbol is defined inside macro ,以下应该工作。如果 foo.c 是:

#define STRINGIFY(x) #x

#define DEBUG_HELP(flag, action) \
do { \
if (strcmp(STRINGIFY(flag), #flag)) && \
strcmp(STRINGIFY(flag), "0")) { \
action; \
} \
} while (0)

#define DEBUGGING(...) DEBUG_HELP(DEBUG_FLAG, printf(__VA_ARGS__))

DEBUGGING("%d\n", 42);

然后:

$ gcc -E -P foo.c               
do { if (strcmp("DEBUG_FLAG", "DEBUG_FLAG")) && strcmp("DEBUG_FLAG", "0")) { printf("%d\n", 42); } } while (0);
$ gcc -E -P foo.c -DDEBUG_FLAG=0
do { if (strcmp("0", "DEBUG_FLAG")) && strcmp("0", "0")) { printf("%d\n", 42); } } while (0);
$ gcc -E -P foo.c -DDEBUG_FLAG
do { if (strcmp("1", "DEBUG_FLAG")) && strcmp("1", "0")) { printf("%d\n", 42); } } while (0);
$ gcc -E -P foo.c -DDEBUG_FLAG=bar
do { if (strcmp("bar", "DEBUG_FLAG")) && strcmp("bar", "0")) { printf("%d\n", 42); } } while (0);

因此,如果 DEBUG_FLAG 未定义或设置为 0,则 if 条件将为假。如果 DEBUG_FLAG 是任何其他内容,除了一个异常(exception),条件将为真。一个异常(exception)是当您有:

#define DEBUG_FLAG DEBUG_FLAG

strcmp 应该在编译时使用 gcc、Clang 和 MSVC 进行评估,尽管我找不到任何保证。作为测试,请参见以下代码:

#include <string.h>
int main(void) {
if (strcmp("foo", "foo"))
return 888;
if (&"foo" != &"foo") // '&' for Clang
return 999;
return 777;
}

编译于 https://godbolt.org/g/2kVShr .

关于C 预处理器 - 根据另一个宏定义不同的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45877926/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com