首页 > 解决方案 > 为什么这个程序会产生与 `YES` 和 `true` 不同的结果?

问题描述

这是完整的程序。你能弄清楚它的控制台输出吗?

#import <Foundation/Foundation.h>

#define kEnv YES

#if kEnv
#define x @"abc"
#else
#define x @"xyz"
#endif


#define kVersion true

#if kVersion
#define y @"abc"
#else
#define y @"xyz"
#endif

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"x: %@; y: %@", x, y);
        NSLog(@"%@", kEnv ? @"abc" : @"cba");
        NSLog(@"%@", kVersion ? @"abc" : @"cba");
    }
    return 0;
}

在继续之前,您可以自己复制和粘贴、运行和检查结果。


输出是:

x: xyz; y: abc
abc
abc

谁能解释原因?

标签: iosobjective-cpreprocessor-directive

解决方案


YES__objc_yes在 <objc/objc.h> 中定义,这是一个编译器级别的符号,预处理器不知道。

(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/objc/objc.h 在我的机器上。)

您可以通过执行查看定义

#define T(X) #X
#define S(X) T(X)
printf("YES is: \"%s\"\n", S(YES));

C 预处理器是一个有趣的野兽。:)

编辑:为什么

#if __objc_yes

表现得好像__objc_yes是假的?因为__objc_yes预处理器完全不知道;只有编译器知道。这是从手册到 GNU 预处理器,但我相信它反映了标准,关于后面的表达式#if可以包含什么:

[...] 不是宏的标识符,它们都被认为是数字零。[...]


推荐阅读