为什么这个程序产生不同的结果与`YES` 和`true`?

如何解决为什么这个程序产生不同的结果与`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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?