Подтвердить что ты не робот

Встроенная функция C99 в формате .c

Я определил свою функцию в .c(без объявления заголовка), как здесь:

inline int func(int i) {
 return i+1;
}

Затем в том же файле ниже я использую его:

...
i = func(i);

И во время ссылки я получил ссылку undefined на "func". Почему?

4b9b3361

Ответ 1

Модель inline в C99 немного отличается от модели большинства людей и, в частности, отличается от той, которая используется С++

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

int func(int i);

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

Итак, ваш пример использования inline в .c файле не имеет большого смысла, лучше просто используйте static для этого, даже дополнительный inline не покупает вас много.

Ответ 2

Внутренняя семантика C99 часто неправильно понимается. Спецификатор inline выполняет две цели:

Во-первых, как подсказка компилятора в случае объявлений static inline и extern inline. Семантика остается неизменной, если вы удаляете спецификатор.

Во-вторых, в случае raw inline (т.е. без static или extern), чтобы предоставить встроенное определение в качестве альтернативы внешнему, которое должно присутствовать в другой единицы перевода. Не предоставление внешнего - это поведение undefined, которое обычно проявляется как связывание с отказом.

Это особенно полезно, если вы хотите поместить функцию в общую библиотеку, но также сделать тело функции доступным для оптимизации (например, вложение или специализация). Предполагая достаточно умный компилятор, это позволяет вам восстановить многие преимущества шаблонов С++, не перепрыгивая через препроцессорные обручи.

Обратите внимание, что это немного более беспорядочно, чем я описал здесь как наличие другой области видимости файла, не входящей в строку, будет инициировать первый случай, как описано в ответе Йенса, даже если само определение inline вместо extern inline, Это по дизайну, поэтому вы можете иметь одно встроенное определение в файле заголовка, которое вы можете включить в исходный файл, который предоставляет внешний, добавив одну строку для внешней декларации.