【问题标题】:Defining something to itself in C preprocessor在 C 预处理器中为自己定义一些东西
【发布时间】:2017-10-17 19:29:23
【问题描述】:

我遇到了这些行:

#define bool  bool
#define false false
#define true  true

我想我不需要多说“wtf?”,但要明确一点:给自己定义一些东西有什么意义?

线路来自clang stdbool.h

【问题讨论】:

  • 只是好奇:你在哪里见过这个?
  • 这基本上只是停止宏扩展。检测到递归宏引用,并阻止进一步扩展。
  • @rsp 这是一个 C++ 链接,而不是 C。
  • 这样您就可以使用#ifdef 进行功能测试。请注意,您正在查看的代码仅适用于 C++,特别是旧版本 C++ 标准的 gcc 扩展。
  • @klutt:这取决于你;我只是将引用的代码放在上下文中。观察 #ifndef __cplusplus / #else 条件句

标签: c c-preprocessor self-reference


【解决方案1】:

C 和 C++ 标准明确允许这样做(并且要求没有无限扩展)

顺便说一句,类似函数的递归(或self-refential)宏更有用:

#define puts(X) (nblines++,puts(X))

(内部puts 是对标准puts 函数的调用;宏通过计数nblines 来“重载”此类进一步调用)

您的定义可能很有用,例如使用像#ifdef true 这样的后续构造,它不能是一个简单的#define true,因为这将“擦除”每次进一步使用true,所以它必须是精确的#define true true

【讨论】:

  • 补充一点,它不会干扰在代码中以其他方式使用令牌。如果它刚刚完成#define true 以允许#ifdef true,那么您不能使用true 作为变量的名称。
  • 我必须说我没有完全看到它的用途。为什么不简单地使用#define true 而不是#define true true
  • @klutt 因为这样true 的所有使用都将被删除。使用#define true true,您可以进行宏测试并仍然使用true,就好像从来没有在它上面定义过宏一样。
  • Quib​​ble:C 和 C++ 标准都不允许 #define bool bool,具体来说,除非你可以在 C 中做到这一点,如果你不这样做 #include <stdbool.h>
【解决方案2】:

它允许用户代码根据这些宏是否定义有条件地编译:

#if defined(bool)
    /*...*/
#else
    /*...*/
#endif

它基本上使您不必用另一个名称(如HAVE_BOOL)污染全局命名空间,前提是该实现让其用户知道iff它提供了一个bool,它还将提供一个同名的宏来扩展它(或者实现可以简单地在内部将它用于它自己的预处理器条件)。

【讨论】:

    【解决方案3】:

    称为自引用宏。

    根据gcv参考:

    自引用宏是其名称出现在其定义中的宏。 回想一下,重新扫描所有宏定义以获取更多宏 代替。如果自引用被认为是宏的使用,它 会产生无限大的膨胀。为了防止这种情况, 自引用不被视为宏调用。它被传递到 预处理器输出不变。

    参考例子:

    自引用的一个常见且有用的用途是创建一个可扩展至自身的宏。如果你写

    #define EPERM EPERM

    然后宏 EPERM 扩展为 EPERM。实际上,它被单独留下 由预处理器在运行文本时使用。你可以告诉 这是一个带有“#ifdef”的宏。如果你愿意,你可以这样做 用枚举定义数字常量,但“#ifdef”为真 每个常数。

    【讨论】:

    • 我可以理解这种用法​​,自引用宏会在这种情况下终止。一开始我无法理解的是如何将此变体编写为实际代码。
    猜你喜欢
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多