【问题标题】:Way to compare strings in C preprocessor? (GCC) [duplicate]在 C 预处理器中比较字符串的方法? (GCC) [重复]
【发布时间】:2016-03-25 15:15:46
【问题描述】:

有没有更好的方法(在 GCC C 中)?

我正在尝试定义一些代表硬件平台的符号,用于条件编译。

但我还想要描述硬件的可打印字符串(用于诊断)。

理想情况下,我希望能够做到:

#define HARDWARE "REV4C"

#if (HARDWARE == "REV4C")
    #define LED_RED      // define pin addresses, blah blah...
#endif

printf("HARDWARE %s\n", HARDWARE);

但我认为这在 C 中是不允许的。这可行,但很丑:

#define REV4C   (403)    // symbols for conditional compilation
#define REV421  (421) 

//#define HARDWARE REV4C // choose hardware platform (just one)
#define HARDWARE REV421

#if (HARDWARE == REV421) // define strings for printing
    #define HARDWARE_ID "REV421"
#elif (HARDWARE == REV4C)
    #define HARDWARE_ID "REV4C"
#else
    #define HARDWARE_ID "unknown"
#endif

#if (HARDWARE == REV421)
    #define LED_RED      // define pin addresses, blah blah...
#endif

/* ... */

printf("HARDWARE_ID %s\n", HARDWARE_ID);

这很难看,因为它需要两个单独的符号,HARDWARE(一个整数,用于比较)和HARDWARE_ID(一个字符串,用于打印)。以及生成HARDWARE_ID 值的逻辑。

有没有更好的办法?


编辑:我不认为这是 how to compare string in C conditional preprocessor-directives 的重复。

该问题(和答案)没有解决如何在不以两个相似符号结尾的情况下获得可打印字符串。

(我在发布这个问题之前确实看过那个答案。)

【问题讨论】:

  • 您的第二个建议还不错。当然,您不应该为您定义的每件事重复#if 块,而是一起定义所有内容。此方法还允许您控制有效值,并允许您在未指定硬件时在#else 子句中发出#error。 (在#ifs 中,未知宏的值为零。)
  • @JosephQuinsey 这个问题没有解决如何获取可打印字符串。
  • 要获得可打印的字符串,请参阅 Jens Gustedt 的回答 Way to compare strings in C preprocessor? (GCC)

标签: c gcc c-preprocessor


【解决方案1】:

通常的做法是定义所需的配置符号,然后有条件地定义所有其他的:

// Select config here
#define REV4C
//#define REV421

#ifdef REV4C
    #define HARDWARE_ID "REV4C"
    #define LED_RED
#elif defined(REV421)
    #define HARDWARE_ID "REV421"
    // .....
#else
//.......
#endif

【讨论】:

  • 并不是我所有的#ifdefs 都在一个这样的地方,所以这个解决方案退化为我原来的“丑陋但有效”的解决方案。
  • @nerdfever.com 重新组织你的代码,让它们在一个地方
  • @M.M 你说得容易。代码已经组织好了,因此某些其他的东西放在一个地方...
【解决方案2】:

要进行实际案例分析,请查看将其标记为重复的注释。要实际上也将值作为字符串,您可以使用字符串化,例如

#define STRINGIFY(...) #__VA_ARGS__
#define HARDWARE_STR STRINGIFY(HARDWARE)

【讨论】:

    【解决方案3】:

    一种完全不同的方法是将依赖于字符串的逻辑移动到 build

    C 预处理器非常有限,但make(以及规则中的 shell 命令)是非常灵活的字符串处理器。例如。使用 GNU make:

    ifeq ($(CONFIG),REV4C)
        HARDWARE_ID = \"REV4C\"
    else
        HARDWARE_ID = \"DEFAULT\"
    endif
    CFLAGS += -DHARDWARE_ID=$(HARDWARE_ID)
    

    并调用为

    gmake CONFIG=REV4C
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      相关资源
      最近更新 更多