Что происходит с внешней встроенной функцией?

Что произойдет, если я определяю свою функцию в моем файле .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 будет рассматривать его как обычную функцию.