【发布时间】:2010-10-13 05:14:36
【问题描述】:
我在使用 iOS 的 Objective-C 开发时遇到了这个问题,但这应该适用于使用 Mac OS X/iOS 链接器的任何 C/C++/Objective-C 代码。 another question 涵盖了该解决方案,但我对为什么感兴趣。
假设我正在使用指向定义常量的库的链接。在头文件中有这样的声明:
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 的情况下有效?我不应该也需要检查它的地址吗?还是它实际上是一致的,而我忽略了一些东西?
【问题讨论】:
-
我认为这通常不适用于 C,因为它依赖于共享库的实现。对于静态链接的库,您只会遇到链接器错误。
-
很公平,我已经编辑了问题。
标签: c darwin weak-linking