我在开发 iOS 的 Objective-C 时遇到了这个问题,但这应该适用于使用 Mac OS X/iOS 链接器的任何 C/C++/Objective-C 代码。另一个问题涵盖了该解决方案,但我对为什么感兴趣。
假设我正在使用指向定义常量的库的链接。在头文件中有这样的声明:
extern char * const BrandNewIdentifier;
我想编译我的应用程序并在具有早期版本库的系统上运行它,其中该常量没有定义,因此为了安全起见,我不认为它已被定义。
现在,如果有一个仅在最新版本的库中定义的函数,我可以这样做:
if (BrandNewFunc) {
BrandNewFunc("foobar", 42);
} else {
printf("Your system does not support some thing.");
}
不包含函数代码的地址,而是BrandNewFunc
计算为 NULL。我认为常量的行为方式相同,但如果我尝试相同的模式,应用程序会在执行检查时死掉(在 iOS 上抛出 EXC_BAD_ACCESS)。具体来说:
if (BrandNewIdentifier) ... // blows up here
取而代之的是检查标识符的地址:
if (&BrandNewIdentifier) {
printf("You got it!");
}
我可以看到逻辑:BrandNewIdentifier
没有价值,所以访问它应该失败。但是,为什么该语法在 的情况下有效BrandNewFunc
?我不应该也需要检查它的地址吗?还是它实际上是一致的,并且我忽略了一些东西?