Компиляция ошибки при использовании -std = gnu99 и встроенной функции
Следующий код:
#include <stdio.h>
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
не компилируется, когда я использую флаг -std=gnu99
(компилирую с помощью gcc). Это ошибка, которую он выдает:
gcc -std=gnu99 -c main.c -o main.o
gcc -std=gnu99 main.o -o main
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `myfunc'
collect2: ld returned 1 exit status
make: *** [main] Error 1
В компиляции нет проблем, когда -std=gnu99
опущен. Кто-нибудь знает, почему компоновщик жалуется, если используется -std=gnu99
?
Ответы
Ответ 1
В C99 вам нужно указать объявление для вашей встроенной функции, например
int myfunc(int);
или разрешить компилятору фактически встроить функцию, указав -finline-functions
или -O3
.
Указание стандарта C99:
Любая функция с внутренней связью может быть встроенной функцией. Для функция с внешней связью, следующие ограничения apply: Если функция объявлена с помощью встроенного спецификатора функции, то он также должен быть определен в той же единице перевода. Если все объявления области файла для функции в переводе единица включает спецификатор встроенной функции без внешнего источника, затем определение в этой единице перевода является встроенным определением. встроенное определение не предоставляет внешнего определения для функции и не запрещает внешнее определение в другом перевод. Встроенное определение предоставляет альтернативу внешнее определение, которое переводчик может использовать для реализации любого вызов функции в том же блоке перевода. Это не указано, использует ли вызов функции встроенный определение или внешнее определение.
Таким образом, компилятор может использовать внешнее определение myfunc
- который не существует, если вы его не предоставляете, следовательно, ошибка компоновщика. Почему он предпочитает выбирать не существующее внешнее определение? Потому что вы запретили встраивание, не используя -finline-functions
или уровень оптимизации, который содержит этот флаг.
Ответ 2
Это gnu_inline
икать. Используйте -std=gnu99 -fgnu89-inline
.
Для получения дополнительной информации см. Атрибуты функции (элемент gnu_inline
).
Соответствующий отрывок:
В C, если функция не является ни внешней, ни статической, то функция компилируется как отдельная функция, а также, если это возможно, внутри нее.
Таким образом, GCC традиционно обрабатывает функции, объявленные inline. Поскольку ISO C99 определяет другую семантику для встроенного, этот атрибут функции предоставляется в качестве меры перехода и как полезная функция в своем собственном праве. Этот атрибут доступен в GCC 4.1.3 и более поздних версиях. Он доступен, если определены оба макроса препроцессора GNUC_GNU_INLINE или GNUC_STDC_INLINE. См. "Встроенная функция" выполняется так же быстро, как макрос.
Ответ 3
Вы должны объявить "myfunc", прежде чем определять его.
Например, этот код можно скомпилировать с опцией -std = gnu99:
#include <stdio.h>
int myfunc(int);
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
ОБНОВЛЕНО
Собственно, относительно стандартного ключевого слова C является только предложение компилятору C. Но компилятор может выбрать не встроенный. Поэтому он может сделать свой собственный путь.
В вашем примере вы можете использовать объявление функции, как я показал выше, или вы можете добавить флаг оптимизации '-O3' (протестирован на linux gcc) и выше - в этом случае ваш исходный код будет скомпилирован без дополнительной декларации.
ОБНОВЛЕНО
Здесь вы можете найти более глубокое объяснение: https://blogs.oracle.com/dew/entry/c99_inline_function
Ответ 4
Очевидно, вам нужно указать, что вы используете, и вы хотите использовать встроенные функции
-fgnu89-inline
Опция -fgnu89-inline указывает GCC использовать традиционную семантику GNU для "встроенных" функций в режиме C99. Этот параметр приняты и проигнорированы версиями 4.1.3 GCC, но не включая 4,3. В версиях GCC 4.3 и более поздних версий он изменяет поведение GCC в режиме C99. Использование этой опции примерно эквивалентно добавлению "gnu_inline" для всех встроенных функций.
Опция -fno-gnu89-inline явно указывает GCC использовать семантику C99 для "inline" в режиме C99 или gnu99 (т.е. указывает поведение по умолчанию). Этот вариант был сначала поддержан в GCC 4.3. Эта опция не поддерживается в режиме C89 или gnu89.
Макросы препроцессора __GNUC_GNU_INLINE__
и __GNUC_STDC_INLINE__
могут использоваться для проверки того, какие семантики находятся в эффект для встроенных функций.
Источник: http://linux.die.net/man/1/gcc
Итак, чтобы скомпилировать ваш код, вам нужно хотя бы это:
gcc source.c -std=gnu99 -fgnu89-inline