使用ifndef和||进行条件编译不会遇到第二种情况

时间:2013-08-30 14:44:27

标签: ios objective-c conditional-compilation

我正在尝试在设置两个定义中的一个或两个时禁用自动崩溃日志报告:我们的调试版本为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)并在整个语句周围加上括号(分别是相同的警告和错误)。

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

2 个答案:

答案 0 :(得分:14)

你想:

#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

答案 1 :(得分: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)