可以在宏内使用`#ifdef`吗?
我只找到这个相关的问题,这并不是我想要的。
我曾经在#ifdef
语句中定义了宏:
#ifdef DEBUG
# define PRINT_IF_DEBUGGING(format) printf(format);
# define PRINTF_IF_DEBUGGING(format, ...) printf(format, __VA_ARGS__);
#else
# define PRINT_IF_DEBUGGING(...)
# define PRINTF_IF_DEBUGGING(...)
#endif
现在,我想进行倒数,以在宏观内有#ifdef
语句。类似的事情:
#define PRINT_IF_DEBUGGING(format, ...) \
#if defined(DEBUG) print(format); #endif
#define PRINTF_IF_DEBUGGING(format, ...) \
#if defined(DEBUG) printf(format, __VA_ARGS__); #endif
但是,我在#ifdef定义
的内部使用__ va_args __
遇到问题。
error: '#' is not followed by a macro parameter
#define PRINT_IF_DEBUGGING(format, ...)
error: '#' is not followed by a macro parameter
#define PRINTF_IF_DEBUGGING(format, ...)
warning: __VA_ARGS__ can only appear in the expansion of a C++11 variadic macro
#if defined(DEBUG) printf(format, __VA_ARGS__); #endif
这可能吗?
I only found this related question, which isn't quite what I am looking for.
I used to have macros defined inside an #ifdef
statement:
#ifdef DEBUG
# define PRINT_IF_DEBUGGING(format) printf(format);
# define PRINTF_IF_DEBUGGING(format, ...) printf(format, __VA_ARGS__);
#else
# define PRINT_IF_DEBUGGING(...)
# define PRINTF_IF_DEBUGGING(...)
#endif
Now, I want to do the inverse, to have the #ifdef
statements inside the macros. Something like this:
#define PRINT_IF_DEBUGGING(format, ...) \
#if defined(DEBUG) print(format); #endif
#define PRINTF_IF_DEBUGGING(format, ...) \
#if defined(DEBUG) printf(format, __VA_ARGS__); #endif
However, I am having an issue using __VA_ARGS__
inside the #ifdef defined
.
error: '#' is not followed by a macro parameter
#define PRINT_IF_DEBUGGING(format, ...)
error: '#' is not followed by a macro parameter
#define PRINTF_IF_DEBUGGING(format, ...)
warning: __VA_ARGS__ can only appear in the expansion of a C++11 variadic macro
#if defined(DEBUG) printf(format, __VA_ARGS__); #endif
Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这确实是一个评论,但是我不能以一种可以让我说出我想说的话的方式格式化,所以我要回答。
无论如何,只需更改此问题:
对此:
等等,这应该解决它。
This should really be a comment, but I can't format that in a way that will allow me to say what I want to say, so I'm answering instead.
Anyway, just change this:
to this:
and so on, and that should fix it.
您不能使用
#ifdef
的内部
#define
,所以不,这是不可能的。您显示的第一个代码是正确的解决方案。You can't use
#ifdef
inside of#define
, so no, this is not possible. The first code you showed is the correct solution.使用
#ifdef
#define
的内部是不可能的。但是,在宏定义中,仍有一些方法可以检测到宏或未定义宏。1。解决方案
godbolt
print_if_if_debugging(foo
debugprint(foo)
debug
是 not 定义:print> print(foo)
示例:
将导致:
2。
is_debug_defined()
在此方面的基本技巧是使用串联 - 如果定义了宏将扩展它,否则代币将被预处理程序未修改:
godbolt
cat
将扩展到check_debug
,因为debug
未定义。cat
将扩展到check_1234
,因为debug
已定义并将其扩展到1234
,然后再与<代码>检查_ 。通过定义一个名为
check_debug
的宏,如果未定义宏,我们可以更改结果,例如:godbolt
debug
,则结果将为〜,〜,0,1
( 4 comma-comma-eplepared separed tokens)debug
,则结果将为check_,0,1
( 3 comma-eparpepared dokens)请注意我们在第一个中如何获得4个令牌案例,但第二个令牌只有3个令牌。
现在,我们要做的就是从该顺序中获取第三代币(如果
debug
未定义,则是0
,并且1
否则),,否则),例如,使用一个始终返回第三参数的简单宏:将其放在一起,这是完整的
is_debug_defined()
看起来像:godbolt
is_debug_defined()
将扩展到0
如果如果debug
未定义,未定义,未定义和1
如果是,例如:使用
is_debug_defined()
您可以使用标准预处理iif ,根据wether << 代码> debug 是定义的。
示例: godbolt
。
3 定义它必须扩展为有效的预处理令牌(因此必须仅包含字母,数字和下划线) - 否则,串联将导致错误。
因此,这将不是工作:
Using
#ifdef
inside of#define
is not possible. But there are still ways you can detect wether or not a macro has been defined within a macro definition.1. Solution
godbolt
PRINT_IF_DEBUGGING(foo)
will expand to:DEBUG
is defined:debugPrint(foo)
DEBUG
is not defined:print(foo)
Example:
would result in:
2. How
IS_DEBUG_DEFINED()
worksThe fundamental trick behind this is to use concatenation - if the macro was defined it will be expanded, otherwise the token will be left unmodified by the preprocessor:
godbolt
CAT
will expand toCHECK_DEBUG
, becauseDEBUG
was not defined.CAT
however will expand toCHECK_1234
, becauseDEBUG
was defined and expanded to1234
before the concatenation withCHECK_
.By defining a macro named
CHECK_DEBUG
we can change the result if the macro was not defined, e.g.:godbolt
DEBUG
is not defined the result will be~, ~, 0, 1
(4 comma-separated tokens)DEBUG
is defined the result will beCHECK_, 0, 1
(3 comma-separated tokens)Notice how we got 4 tokens in the first case, but only 3 tokens in the second.
Now all we need to do is take the 3rd token from that sequence (which will be
0
ifDEBUG
is not defined and1
otherwise), for example with a simple macro that always returns the 3rd argument:Putting it all together, this is what a full
IS_DEBUG_DEFINED()
could look like:godbolt
IS_DEBUG_DEFINED()
will expand to0
ifDEBUG
is not defined, and1
if it is, e.g.:With
IS_DEBUG_DEFINED()
you can then use a standard preprocessorIIF
to change the behaviour of your macro depending on wetherDEBUG
is defined or not.Example: godbolt
3. Caveats
One small caveat with this is that if
DEBUG
is defined it must expand to a valid preprocessing token (so it must only contain letters, digits and underscores) - otherwise the concatenation will result in an error.So this would not work: