Что происходит с внешней встроенной функцией?
Что произойдет, если я определяю свою функцию в моем файле .h как
extern int returnaint(void);
определите его в соответствующем .c файле как
inline int returnaint(void) {
return 1;
}
и включить заголовок в другой .c файл и использовать функцию? Когда я компилирую вещи отдельно, создавая объектный файл для каждого .c файла, а затем связываю их, включена ли встроенная функция или что происходит?
Я знаю, что компилятор может игнорировать inline
, но что, если он не игнорирует его в этом случае?
Ответы
Ответ 1
Добавление inline
в определение функции в файле .c
просто лишнее.
-
В вашей части компиляции файла .c
отображается объявление extern
(без inline
) и определение inline
. Таким образом, он выдает символ для функции в объектном файле.
-
Все остальные единицы компиляции видят только объявление extern
, и поэтому они могут использовать эту функцию без проблем, если вы связываете свой окончательный исполняемый файл с другим файлом .o
.
На самом деле, вы просто ошибаетесь. Эта функция предназначена для использования в определении inline
в файле .h
, видимом для всех. Это определение функции действует только как объявление символа, так же как extern
, но не определяет его.
Объявление extern
только в одном файле .c
(блок компиляции) гарантирует, что символ определен там.
Терминология немного запутанна, определение inline
, действующее как объявление символа, и extern
декларация, выступающая в качестве ее определения
Ответ 2
Он не будет компилироваться. От C11 (ISO/IEC 9899: 2011) §6.7.4 Спецификаторы функций (выделено мной):
Любая функция с внутренней связью может быть встроенной функцией. Для функции с внешним привязка, применяются следующие ограничения: Если функция объявлена с помощью спецификатора встроенной функции, то она также должна быть определена в одной и той же единицы перевода. Если все декларации области файла для функции в блоке перевода включают встроенную функцию спецификатор без extern, тогда определение в этой единице перевода является встроенным определение. Встроенное определение не обеспечивает внешнего определения функции, и не запрещает внешнее определение в другой единицы перевода. Встроенное определение обеспечивает альтернативу внешнему определению, которое переводчик может использовать для реализации любой вызов функции в одной и той же единице перевода. Не указано, является ли вызов функция использует встроенное определение или внешнее определение. 140)
140) Поскольку встроенное определение отличается от соответствующего внешнего определения и от любого другого соответствующие встроенные определения в других единицах перевода, все соответствующие объекты со статическим хранилищем длительность также различна в каждом из определений.
Другой .c
файл получает только объявление функции inline
из заголовка, но не определение, поэтому оно против правила выделено жирным шрифтом.
EDIT:
Как указывает @Jens Gustedt, мое предыдущее объяснение неверно, потому что в вопросе OP функция объявляется как не-встроенная в заголовочном файле:
extern int returnaint(void);
Таким образом, другой файл .c
будет рассматривать его как обычную функцию.