C/C++中的单行#ifdef指令

6

考虑以下简单的C/C ++示例:

#define FOO
...
#ifdef FOO
  bar++;
#endif

好的,现在我想要将这个(以及类似的)条件语句压缩成一行,以便于代码可读性(代码中有数十个单行语句,每个语句都需要根据不同的定义进行条件判断)。使用时应该像这样:

#define FOO
...
MY_IFDEF(FOO,bar++;) //Single-line conditional

目标是拥有一个可重用的宏,可以接受任意标识符,如果先前已经使用#define定义了该标识符,则编译语句,并在一行中完成所有操作。

有什么想法吗?

更新0:代码必须能够同时编译为C和C++。


2
我认为你不能让宏扩展到#ifdef;扩展不会被扫描条件。 - Nate Eldredge
你可以在if条件语句中调用函数和匹配宏的相应值,如果条件成立,就可以执行任何你想要的操作。 - Jarvis__-_-__
除非询问两种语言之间的差异或交互作用,否则不要同时标记C和C ++。如果您想获得两种语言的答案,可以提出单独的问题。选择一个标签并删除另一个。 - Eric Postpischil
看起来你不知道 #undef 是什么。 - Алексей Неудачин
2个回答

5

在扩展宏的过程中,您无法使用#ifdef ,但是您完全可以预先检查并声明空语句,以防条件不满足。

#ifdef FOO
  #define MY_IFDEF(x,y) some-processing-you-need
#else
  #define MY_IFDEF(x,y) ;
#endif

另外还要注意 C++ 的新特性: constexpr,它也是可用的。


这个解决方案不能处理任意标识符,并且需要预定义每个标识符的类似部分(这些部分不一定在我事先知道)。 "MY_IFDEF" 中的 "x" 正是这样一个标识符的参数。 - Regus Pregus
@RegusPregus 是的,如其他回答所提到的,您应该使用constexpr或if来进行单行定义。 - Alex

2

更新4: 正如@Alex Bakanov所指出的,您不能在扩展宏时使用#ifdef,因此没有一种适用于所有情况的单行解决方案。尽管如此,我希望我在这里写的想法可能会有用。

如果您使用#define FOO 1#define FOO 0,则可以使用#defineif constexpr的组合。请注意,如果未定义FOO,则会出现错误。此程序将返回1:

#include<iostream>

#define FOO 1
#define MY_IFDEF(x,y) if constexpr (x) y;

int main()
{
    int bar =0;
    MY_IFDEF(FOO,bar++)

    std::cout << bar << "\n";  
}

更新:根据@eerorika的评论,为了避免如果未定义FOO而出现错误,必须添加以下声明:

constexpr bool FOO = false;

更新2:这个版本在任何情况下都可以工作,唯一的问题是它是否值得努力?

#ifdef FOO
    constexpr bool USED_FOO = true;
#else
    constexpr bool USED_FOO = false;
#endif

#define MY_IFDEF(x,y) if constexpr (USED_##x) y ;

更新3:兼容C语言版本。请注意,理论上在这种情况下它是在运行时而非编译时进行评估,但编译器将意识到它始终为真/假并相应地生成代码:

#ifdef FOO
    const static bool USED_FOO = true;
#else
    const static bool USED_FOO = false;
#endif

#define MY_IFDEF(x,y) if (USED_##x) y;

好的,你是对的,但它不能被定义为编译器选项。 - Laci
1
重点是无条件地定义变量,并根据宏是否被定义来选择值。 - eerorika
constexpr 只在 C++ 中可用,而不是 C,我的代码必须同时编译两者。这是我没有在问题中清楚说明的错误。 - Regus Pregus
严格来说,你是正确的,但如果省略constexpr,第一段代码也可以工作,这是符合C标准的...顺便问一下:OP是什么? - Laci
顺便提一下,_FOO是一个保留标识符。所有以下划线后跟另一个下划线或大写字母开头的标识符都为实现保留。 - Christian Gibbons
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接