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

Компиляция ошибки при использовании -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?

4b9b3361

Ответ 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