Я столкнулся с этой проблемой при разработке в Objective-C для iOS, но это должно относиться к любому коду C / C ++ / Objective-C, использующему компоновщик Mac OS X / iOS. Решение покрыто другим вопросом , но меня интересует почему .
Допустим, я использую ссылку на библиотеку, которая определяет константу. В заголовочном файле есть объявление вроде этого:
extern char * const BrandNewIdentifier;
Я хочу скомпилировать свое приложение и запустить его в системе с более ранней версией библиотеки, где эта константа не имеет определения, поэтому, для безопасности, я не думаю, что она была определена.
Теперь, если есть функция, которая определена только в самой последней версии библиотеки, я могу сделать это:
if (BrandNewFunc) {
BrandNewFunc("foobar", 42);
} else {
printf("Your system does not support some thing.");
}
Вместо того, чтобы содержать адрес кода функции, BrandNewFunc
оценивается как NULL. Я бы подумал, что константа будет вести себя так же, но если я попробую тот же шаблон, приложение умирает при выполнении проверки (выбрасывает EXC_BAD_ACCESS на iOS). В частности:
if (BrandNewIdentifier) ... // blows up here
Вместо этого проверяется адрес идентификатора:
if (&BrandNewIdentifier) {
printf("You got it!");
}
Я вижу логику: BrandNewIdentifier
не имеет значения, поэтому доступ к нему должен завершиться неудачей. Но тогда почему этот синтаксис работает в случае BrandNewFunc
? Разве я не обязан также проверять его адрес? Или это действительно непротиворечиво, и я что-то упустил из виду?