Я столкнулся с этой проблемой при разработке в Objective-C для iOS, но это должно применяться к любому C/C++/Objective-C-коду с использованием компоновщика Mac OS X/iOS. Решение покрыто another question, но меня интересует , почему.Проверка наличия внешних идентификаторов в C
Предположим, что я использую ссылку на библиотеку, которая определяет константу. В файле заголовка есть декларация, как это:
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
? Не следует ли мне также проверять его адрес? Или это на самом деле непротиворечиво, и я кое-что упустил из виду?
Я не думаю, что это относится к C вообще, поскольку оно будет зависеть от реализации общей библиотеки. Для статически связанных библиотек у вас просто есть ошибки компоновщика. – jamesdlin
Справедливо, я отредактировал вопрос. – benzado