Цель C: встроенная функция - символ не найден

У меня есть библиотека, которая использует встроенную функцию C, и компилируется просто отлично. Когда другая библиотека ссылается на эту библиотеку, она все равно хорошо компилируется. Но если реальное приложение ссылается на библиотеку, оно не может скомпилировать, говоря, что символ _functionNameHere (да, имя функции, начинающееся с подчеркивания) не найден.

Если я удаляю встроенный спецификатор, все это прекрасно компилируется. Но пока функция встроена в библиотеку, приложение не может компилироваться!

Есть идеи, почему это так?

Я знаю довольно много о компиляторах, но я новичок в Objective-C, и все, что я знаю об этом, является не чем иным как образованными догадками. И даже таким образом, я не могу придумать причину, по которой он будет вести себя так.

Дело в том, что встроенная функция - это INLINE, что означает, что символа вообще нет, он компилируется внутри строки, где бы он ни вызывался, и ссылочное приложение не должно даже знать, что оно когда-либо существовало. Это верно до тех пор, пока встроенная функция всегда встраиваема и доступна для библиотеки, и нет специальной конфигурации компилятора, которая предотвращает встраивание, и все это верно.

Так что, пожалуйста, приходите и указывайте пальцем за то, что я делаю / неправильно думаю ...

Спасибо: -)

12
задан Daniel 18 August 2010 в 16:38
поделиться

1 ответ

В определение встроенной функции следует добавить спецификатор static, если функция предназначена для использования только в той же единице перевода (внутренняя связь),

static inline int add(int x, int y) {return x+y;}
int s = add(1, 2);

Если вы опустите static в приведенном выше примере (в конфигурации отладки, где не выполняется оптимизация и не выполняется встраивание), компоновщик завершит работу с ошибкой, жалуясь на то, что _add ссылается, но символы не найдены.

В C99 объявление встроенной функции без какого-либо спецификатора хранилища не будет генерировать фактическое тело вызываемой функции, поэтому компоновщик выдает ошибку, когда она ему нужна.

Если ваша встроенная функция может использоваться другими модулями, это сложнее. Обычной практикой является включение определения встроенной функции (без внешней) в заголовочный файл и включение ровно одно объявление прототипа с extern ровно в одном модуле.

Хорошая статья, объясняющая встроенные функции в C99: http://www.drdobbs.com/184401540

36
ответ дан 2 December 2019 в 04:08
поделиться