Недавно я столкнулся с проблемой в моем проекте. Обычно я компилирую его в gcc-4, но после попытки компилировать в gcc-3, я заметил другую обработку встроенных функций. Чтобы проиллюстрировать это, я создал простой пример:
main.c:
#include "header.h"
#include <stdio.h>
int main()
{
printf("f() %i\n", f());
return 0;
}
file.c:
#include "header.h"
int some_function()
{
return f();
}
header.h
inline int f()
{
return 2;
}
Когда я компилирую код в gcc-3.4.6 с помощью:
gcc main.c file.c -std=c99 -O2
Я получаю ошибку компоновщика (множественное определение f), то же самое, если убрать флаг -O2
. Я знаю, что компилятору не нужно ничего вставлять, если он этого не хочет, поэтому я предположил, что он поместил f в объектный файл вместо того, чтобы вставлять его в случае как main.c
, так и file.c
, таким образом, ошибка множественного определения. Очевидно, я мог бы исправить это, сделав f
статическим, а затем, в худшем случае, иметь несколько f
в двоичном файле.
Но я попытался скомпилировать этот код в gcc-4.3.5 с помощью:
gcc main.c file.c -std=c99 -O2
И все работало нормально, поэтому я предположил, что более новый gcc встраивал f
в обоих случаях, и в двоичном файле вообще не было функции f
(проверено в gdb, и я был прав).
Однако, когда я убрал флаг -O2
, я получил две неопределенные ссылки на int f()
.
И здесь я действительно не понимаю, что происходит. Похоже, что gcc предполагал, что f
будет встроенным, поэтому он не добавил его в объектный файл, но позже (потому что -O2
не было) он решил генерировать вызовы этих функций вместо встраивания, и именно здесь ошибка компоновщика.
Теперь встает вопрос: как мне определять и объявлять простые и маленькие функции, которые я хочу встроить, чтобы их можно было использовать на протяжении всего проекта, не опасаясь проблем в различных компиляторах? И делает ли их все статичные правильные вещи? Или, может быть, gcc-4 не работает, и у меня никогда не должно быть нескольких определений встроенных функций в нескольких единицах перевода, если они не статичны?