【问题标题】:macro dependent macro宏依赖宏
【发布时间】:2011-02-07 23:35:15
【问题描述】:

是否可以这样做:

  #define F(x) \
    #ifdef DOUBLE \
      2*x \
    #else \
      x \
    #endif

所以当我使用F 时,它扩展到什么取决于是否定义了宏DOUBLE?我不这么认为,但我充满希望。 GNU 扩展很好。

编辑 作为对一些答案的回应,我真的在使用它来进行一些代码生成,其中代码根据定义的位置而略有不同。由于包含某些文件的顺序以及需要定义相关宏的位置,因此以这种方式切换它需要一些因素。我可能不得不这样做,但如果我不必从这个角落把自己画下来,我会很高兴!

【问题讨论】:

    标签: c gcc macros c-preprocessor


    【解决方案1】:

    怎么了

    #ifdef DOUBLE
      #define F(x) (2 * (x))
    #else
      #define F(x) (x)
    #endif
    

    【讨论】:

      【解决方案2】:

      如果我们可以约束问题,您就可以做到这一点。具体来说,如果您可以保证DOUBLE

      • 未定义为宏,或
      • 定义为扩展为空标记序列的宏(例如#define DOUBLE),

      那么您可以使用带有标记连接的间接方法:

      #define F_IMPL_(x)       DOUBLE_IS_DEFINED
      #define F_IMPL_DOUBLE(x) DOUBLE_NOT_DEFINED
      
      #define F_1(x, m) F_2(x, m)
      #define F_2(x, m) F_IMPL_ ## m ( x )
      
      #define F(x) F_1(x, DOUBLE)
      

      使用示例:

      F(t)
      #define DOUBLE
      F(t)
      

      预处理后的结果:

      DOUBLE_NOT_DEFINED
      DOUBLE_IS_DEFINED
      

      如果DOUBLE(如果已定义)被定义为扩展为单个已知标记的宏,并且该标记可以构成标识符的一部分(例如,TRUE1 )。要处理此问题,您只需将 F_IMPL_ 宏重命名为 F_IMPL_{TOKEN}(例如,F_IMPL_TRUEF_IMPL_1)。

      【讨论】:

      • 干得好。不过我不想维护它。
      【解决方案3】:

      为什么不反过来嵌套呢?

      #ifdef DOUBLE
      #define F(x) (2*(x))
      #else
      #define F(x) (x)
      #endif 
      

      【讨论】:

        【解决方案4】:

        没有。您可以做的最接近的事情是将其放入头文件中,并在每次您关心的定义更改时#include 该头文件。这有时被称为“X”模式,因为X 被用作更改定义的宏。

        例如,该模式的一种常见用法是自动生成枚举值的字符串名称:

        // File myenum_values.h
        // NOTE: _no_ header guards so we can include this file multiple times
        X(Apple)
        X(Orange)
        X(banana)
        
        // File myenum.h
        enum Fruit
        {
        #define X(x) x,
        #include "myenum_values.h"
        }
        
        const char *FruitNames[] =
        {
        #undef X
        #define X(x) #x,
        #include "myenum_values.h"
        };
        
        // We now have an array of fruit names without having to define the enum twice
        

        【讨论】:

          猜你喜欢
          • 2023-04-10
          • 1970-01-01
          • 2020-08-12
          • 2019-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多