【问题标题】:Compare macros containing parentheses比较包含括号的宏
【发布时间】:2015-11-28 14:49:35
【问题描述】:

在cygwin的sys/time.c文件中,定义如下:

#define CLOCK_REALTIME (clockid_t)1
#define CLOCK_PROCESS_CPUTIME_ID (clockid_t)2
#define CLOCK_THREAD_CPUTIME_ID (clockid_t)3
#define CLOCK_MONOTONIC (clockid_t)4

我正在尝试编译的程序从上述宏中定义了一个宏...

/* make sure we have a best effort CUSTOM_CLOCK_MONOTONIC we can rely on */
#if defined(CLOCK_MONOTONIC)
#define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC
#elif defined(CLOCK_HIGHRES)
#define CUSTOM_CLOCK_MONOTONIC CLOCK_HIGHRES
#else
#define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME
#endif

稍后检查自定义宏是否等于另一个宏...

#if CUSTOM_CLOCK_MONOTONIC != CLOCK_REALTIME
    if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) == 0) {
        return;
    }
#endif

但是,由于宏是用括号定义的,GCC 编译器无法成功处理它们,从而产生错误:

test.c: In function 'main':
test.c:4:36: error: missing binary operator before token "4"
 #define CLOCK_MONOTONIC (clockid_t)4
                                    ^
test.c:7:32: note: in expansion of macro 'CLOCK_MONOTONIC'
 #define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC
                                ^
test.c:16:5: note: in expansion of macro 'CUSTOM_CLOCK_MONOTONIC'
 #if CUSTOM_CLOCK_MONOTONIC != CLOCK_REALTIME
     ^

有什么方法可以比较两个宏而不产生错误?

【问题讨论】:

  • 定义应该至少添加一对圆括号:#define CLOCK_REALTIME (clockid_t)1 -->> #define CLOCK_REALTIME ((clockid_t)1)
  • 由于这些宏不符合要求,它们必须能够以您尝试过的方式在 #if 表达式中使用。确保这一点的常见策略是添加+ 标志,例如#define CLOCK_REALTIME ((clockid_t)+1)
  • 灵感来自:lwn.net/Articles/64207

标签: c macros c-preprocessor


【解决方案1】:

在这种情况下,您只需更改:

#if CUSTOM_CLOCK_MONOTONIC != CLOCK_REALTIME
    if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) == 0) {
        return;
    }
#endif

if (CUSTOM_CLOCK_MONOTONIC != CLOCK_REALTIME) {
     if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) == 0) {
         return;
     }
}

如果不等式在所有现代编译器中为假,则代码也将被优化。

【讨论】:

    【解决方案2】:

    无法测试某个宏是否定义为某个其他特定宏。如果您需要此功能,则必须“记住”使用另一个宏。例如:

    #if defined(CLOCK_MONOTONIC)
    #define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC
    #define CUSTOM_CLOCK_IS_MONOTONIC
    #elif defined(CLOCK_HIGHRES)
    #define CUSTOM_CLOCK_MONOTONIC CLOCK_HIGHRES
    #define CUSTOM_CLOCK_IS_HIGHRES
    #else
    #define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME
    #define CUSTOM_CLOCK_IS_REALTIME
    #endif
    

    以后你可以测试

    #ifndef CUSTOM_CLOCK_IS_REALTIME
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-24
      • 2021-10-24
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多