Я определил свою функцию в .c(без объявления заголовка), как здесь:
inline int func(int i) {
return i+1;
}
Затем в том же файле ниже я использую его:
...
i = func(i);
И во время ссылки я получил ссылку undefined на "func". Почему?
Я определил свою функцию в .c(без объявления заголовка), как здесь:
inline int func(int i) {
return i+1;
}
Затем в том же файле ниже я использую его:
...
i = func(i);
И во время ссылки я получил ссылку undefined на "func". Почему?
Модель inline
в C99 немного отличается от модели большинства людей и, в частности, отличается от той, которая используется С++
inline
- это только подсказка, что компилятор не жалуется на двузначные символы. Это не гарантирует, что функция встроена, и фактически не создается символ, если это необходимо. Чтобы заставить генерировать символ, вам нужно добавить своего рода экземпляр после определения inline
:
int func(int i);
Обычно вы должны иметь определение inline
в файле заголовка, которое затем включается в несколько файлов .c(единицы компиляции). И вы должны иметь только указанную выше строку в одном из блоков компиляции. Вероятно, вы видите только эту проблему, потому что вы не используете оптимизацию для своего компилятора.
Итак, ваш пример использования inline
в .c файле не имеет большого смысла, лучше просто используйте static
для этого, даже дополнительный inline
не покупает вас много.
Внутренняя семантика C99 часто неправильно понимается. Спецификатор inline
выполняет две цели:
Во-первых, как подсказка компилятора в случае объявлений static inline
и extern inline
. Семантика остается неизменной, если вы удаляете спецификатор.
Во-вторых, в случае raw inline
(т.е. без static
или extern
), чтобы предоставить встроенное определение в качестве альтернативы внешнему, которое должно присутствовать в другой единицы перевода. Не предоставление внешнего - это поведение undefined, которое обычно проявляется как связывание с отказом.
Это особенно полезно, если вы хотите поместить функцию в общую библиотеку, но также сделать тело функции доступным для оптимизации (например, вложение или специализация). Предполагая достаточно умный компилятор, это позволяет вам восстановить многие преимущества шаблонов С++, не перепрыгивая через препроцессорные обручи.
Обратите внимание, что это немного более беспорядочно, чем я описал здесь как наличие другой области видимости файла, не входящей в строку, будет инициировать первый случай, как описано в ответе Йенса, даже если само определение inline
вместо extern inline
, Это по дизайну, поэтому вы можете иметь одно встроенное определение в файле заголовка, которое вы можете включить в исходный файл, который предоставляет внешний, добавив одну строку для внешней декларации.