如何解决为什么这个程序产生不同的结果与`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
谁能解释一下原因?
解决方法
如果添加
#define YES 1
一开始你会得到你期望的输出。原因是 YES
定义可能比这里给出的方式更复杂,并且会弄乱预处理器。您可以通过例如测试将您的测试更改为
#if YES
(并删除我对 YES 的定义),您将获得与之前相同的结果。这只是表明,无论 YES
是如何定义的,它都不会触发
#if YES
测试。
附注
我想如果你想使用常量,例如
#if XXX
或
#if XXX > 5
您需要将 XXX
定义为数值,否则预处理器无法正确执行评估。我建议你坚持只检查定义,例如只需使用
#ifdef XXX
以及什么时候需要使用
#if
只使用数字常量,不使用任何表达式。
此处提到的 FWIW https://en.wikipedia.org/wiki/C_preprocessor 预处理器非常有限 - 参考资料讨论了一些限制。
,YES
在 __objc_yes
,这是一个编译器级别的符号,预处理器不知道。
(我机器上的/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
对预处理器来说是完全未知的;只有编译器知道。这是从 manual 到 GNU 预处理器,但我相信它反映了标准,关于 #if
之后的表达式可以包含什么:
[...] 不是宏的标识符,它们都被认为是数字零。 [...]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。