【问题标题】:Wild-card style C preprocessor trick通配符风格的 C 预处理器技巧
【发布时间】:2021-06-26 07:45:22
【问题描述】:

我有很多编译标志可以为不同的客户配置我的程序。 例如:MODE_A_1MODE_A_2MODE_B_1、...MODE_AB_54、...

我真的很想要一些预处理器技巧,让我可以编写这样的伪代码:

#ifdef MODE_A_.*

不必键入每个 MODE_A_.. 出现:

#if defined(MODE_A_1) && defined(MODE_A_2) && ...

如果可以应用正则表达式会更酷。

【问题讨论】:

  • 如果需要定义任何MODE_A_ 标志,则增强构建以定义MODE_A。这对于任何现代构建系统都应该很简单。
  • 问题是我不仅有 2 个参数(字母和数字),而且还有更多。我必须写下所有的组合数
  • 不,问题是您混合了功能标志和目标。您只需要构建系统(或某处的标头)来启用基于目标的实际功能标志列表。然后,您的所有条件都可以依赖于一个相关的功能标志。
  • @Useless 这就是 Boost 使用的。我认为 Windows.h 也是这样做的

标签: c c-preprocessor wildcard


【解决方案1】:

与其使用宏名称,不如让宏名称成为表示特征的位模式。例如

#define FEAT_VCORNERS        0x01
#define FEAT_VPANEL          0x02
#define FEAT_DOOR_FULL_PANEL 0x04

好的,因此它将您限制为 32 个单独的功能 - 数量不多,但可能就足够了

然后为每个客户定义他们拥有的功能。模式是否重复并不重要

#define CUST_A (FEAT_VCORNERS)
#define CUST_B (FEAT_VCORNERS)
#define CUST_C (FEAT_VPANEL | FEAT_DOOR_FULL_PANEL)
#define CUST_D (FEAT_VCORNERS | FEAT_VPANEL)

在构建输入中,您可以定义 -DCUST=CUST_D。在代码中,你只需要测试

#if CUST & FEAT_VCORNERS
...
#endif

【讨论】:

    【解决方案2】:

    我有很多编译标志可以为不同的客户配置我的程序。例如:MODE_A_1MODE_A_2MODE_B_1、...MODE_AB_54、...

    但“MODE_A_1”不是客户。您在非常基本的层面上混淆了两个完全不同的东西。

    如果您想要一个可以为不同客户独立启用/禁用的功能列表,请使用类似

    #if defined(CUSTOMER_GUILLAUME)
    
    #define ENABLE_FEATURE_A
    #define ENABLE_FEATURE_1
    
    #elif defined(CUSTOMER_USELESS)
    
    #define ENABLE_FEATURE_B
    #define ENABLE_FEATURE_2
    
    // ...
    
    #endif
    

    然后代替

    #if defined(MODE_A_1) && defined(MODE_A_2) && ...
    

    你只是使用

    #if defined(ENABLE_FEATURE_A)
    

    请注意,我只是在使用开/关功能标志。如果您需要更精细的控制,例如#if (FEATURE_C_VERSION > 123) ...

    ,您可以将它们设置为整数版本号

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-16
      • 2014-10-26
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 2016-09-02
      • 1970-01-01
      相关资源
      最近更新 更多