11

当设置了两个定义中的一个或两个时,我试图禁用自动崩溃日志报告:DEBUG对于我们的调试版本和INTERNATIONAL国际版本。但是,当我在这种情况下尝试这样做#ifndef时,我会收到警告Extra tokens at end of #ifndef directive,并且以DEBUG定义的方式运行将触发 Crittercism。

#ifndef defined(INTERNATIONAL) || defined(DEBUG)
    // WE NEED TO REGISTER WITH THE CRITTERCISM APP ID ON THE CRITTERCISM WEB PORTAL
    [Crittercism enableWithAppID:@"hahayoudidntthinkidleavetherealonedidyou"];
#else
    DDLogInfo(@"Crash log reporting is unavailable in the international build");

    // Since Crittercism is disabled for international builds, go ahead and
    // registers our custom exception handler. It's not as good sadly
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    DDLogInfo(@"Registered exception handler");
#endif

这个真值表显示了我的期望:

INTL defined | DEBUG defined | Crittercism Enabled
     F       |      F        |    T
     F       |      T        |    F
     T       |      F        |    F
     T       |      T        |    F

这在它只是#ifndef INTERNATIONAL. 我也试过defined(blah)在整个语句周围不带括号(分别是相同的警告和错误)。

如何从编译器获得我想要的行为?

4

2 回答 2

21

你要:

#if !defined(INTERNATIONAL) && !defined(DEBUG)
    // neither defined - setup Crittercism
#else
    // one or both defined
#endif

或者你可以这样做:

#if defined(INTERNATIONAL) || defined(DEBUG)
    // one or both defined
#else
    // neither defined - setup Crittercism
#endif
于 2013-08-30T14:46:09.327 回答
0

我刚刚发现一篇Conditional Compilation 可以从语法级别更好地解释#if/#elif#ifdef/之间的差异:#ifndef

  • #if constant-expression newline
  • #ifdef identifier newline
  • #ifndef identifier newline
  • #else newline
  • #elif constant-expression newline
  • #endif newline

所以在这里我们可以看到#ifndef必须跟'标识符',这通常是指令定义的宏#define,或者@rmaddy 说'单个值'。

但是if后面可以跟'constant-expression' 这样条件表达式defined(INTERNATIONAL) || defined(DEBUG)还是!defined(INTERNATIONAL) && !defined(DEBUG)可以使用的。

于 2021-02-26T06:03:24.253 回答