I ran into this problem while developing in Objective-C for iOS, but this should apply to any C/C++/Objective-C code using the Mac OS X/iOS linker. The solution is covered by another question, but I'm interested in the why.
Let's say I'm using a linking to a library which defines a constant. In a header file there is a declaration like this:
extern char * const BrandNewIdentifier;
I want to compile my application and run it on a system with an earlier version of the library, where that constant has no definition, so to be safe I don't assume it has been defined.
Now, if there's a function that is only defined in the most recent version of the library, I can do this:
if (BrandNewFunc) {
BrandNewFunc("foobar", 42);
} else {
printf("Your system does not support some thing.");
}
Instead of containing the address of function code, BrandNewFunc
evaluates to NULL. I would think that the constant would behave the same way, but if I try the same pattern, the app dies while performing a check (throws EXC_BAD_ACCESS on iOS). Specifically:
if (BrandNewIdentifier) ... // blows up here
What works instead is checking the address of the identifier:
if (&BrandNewIdentifier) {
printf("You got it!");
}
I can see the logic: BrandNewIdentifier
has no value, so accessing it should fail. But then why does that syntax work in the case of BrandNewFunc
? Shouldn't I be required to check its address also? Or is it actually consistent, and there is something I've overlooked?