【问题标题】:single-line #ifdef in C/C++C/C++ 中的单行 #ifdef
【发布时间】:2021-08-29 06:20:12
【问题描述】:

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

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

好的,现在我想为了代码可读性将那个(和任何其他类似的)条件放入一行中(代码有数十个单行语句,每个语句都需要有条件,具体取决于 不同 定义)。使用时的样子:

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

我们的目标是拥有一个可重用的宏,它可以采用任意标识符,如果该标识符先前已被#define-d 编译,则编译语句,并在一行中完成所有操作。

有什么想法吗?

UPDATE0:代码必须为 C 和 C++ 编译

【问题讨论】:

  • 我不认为你可以将宏扩展为#ifdefs;不扫描扩展以查找条件。
  • 你可以在if条件下创建函数并匹配宏的对应值,如果为真则为所欲为
  • 除非询问语言之间的差异或交互,否则不要同时标记 C 和 C++。如果您想要两种语言的答案,您可以提出单独的问题。选择一个标签并删除另一个。
  • 看来你不知道#undef

标签: c c-preprocessor preprocessor


【解决方案1】:

你不能在扩展宏的时候使用#ifdef,但是你完全可以预先检查它,如果条件不满足就声明空语句。

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

还可以查看 C++ 的新功能:constexpr 这也可以使用。

【讨论】:

  • 此解决方案不适用于任意标识符,并且需要为每个标识符预定义类似的部分(我不一定事先知道)。 MY_IFDEF 中的“x”正是此类标识符的参数。
  • @RegusPregus 是的,如其他答案中所述,您应该使用 constexpr 或 if 进行单行定义。
【解决方案2】:

UPDATE4:正如@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;

UPDATE2:此版本适用于任何情况,唯一的问题是值得付出努力吗?

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

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

UPDATE3: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;

【讨论】:

  • 好建议。通过使用 constexpr bool 变量,类似的工作不需要#define FOO 0
  • @eerorika 你什么意思?如果未定义 FOO,MY_IFDEF(FOO,bar++) 总是会报错。
  • 使用变量可以避免该错误。
  • 好的,你说得对,但不能定义为编译器选项
  • 重点是无条件定义变量,根据是否定义宏来选择值。
猜你喜欢
  • 2010-11-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2010-12-10
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
相关资源
最近更新 更多