Предупреждение gcc: функция используется, но не определена

Я получаю предупреждение: function used but not defined. У меня static __inline__ в файле заголовка сказано a.h. Заголовочный файл включен в a.c. Я хотел бы поместить все эти встроенные функции, которые находятся в файлах заголовков, в файлы .c. Следующий код дает представление о моей проблеме.

Оригинальный код:

a.h:

static __inline__ function1(){
    function definition;  
}

Я изменил:
a.h:

static function1();

a.c:

#include "a.h"

static function1(){
   function definition;
}

Сделав это выше, я получил предупреждение:

   warning: function function1 is used but not defined. 

Не могли бы вы сообщить мне, почему я получаю такое предупреждение? Я хотел бы перенести всю функцию __inline__ в .c, чтобы я не получал предупреждения:

  warning: function1 is could not be inlined, code size may grow.

заранее спасибо


person thetna    schedule 02.04.2011    source источник
comment
Исправьте форматирование кода в своем коде; это беспорядок!   -  person Lightness Races in Orbit    schedule 03.04.2011
comment
Не забудьте указать тип возвращаемого значения для каждой функции - вы используете C99, а C99 требует этого.   -  person Jonathan Leffler    schedule 03.04.2011


Ответы (3)


Вы объявили функцию статической. Это означает, что он виден только в текущей единице компиляции. Другими словами: реализация видна только внутри файла a.c. Вам необходимо удалить ключевое слово static как в a.h, так и в a.c, чтобы другие файлы .c могли видеть функцию. Вы должны указать возвращаемое значение, например void function1();, потому что это неявно int, если вы его не указали.

person DarkDust    schedule 02.04.2011

Функции, объявленные static в .c файле, видимы / могут использоваться только в этом файле. Если они в нем не используются, то это фактически мертвый код, и компилятор предупреждает вас об этом факте. В GCC вы можете использовать unused атрибут функции, чтобы подавить это предупреждение:

static int __attribute__((unused)) function1() {
...
}

РЕДАКТИРОВАТЬ:

Как правило, вы должны следовать следующим рекомендациям относительно встроенных функций:

  • Если они используются в нескольких файлах C, объявите их static и укажите их определение во включенном файле заголовка. Это позволяет всем .c файлам, включающим этот заголовок, иметь собственное частное определение функции, что позволяет компилятору встроить его. Одинокая static функция прототипы практически не имеет смысла в файле заголовка, который будет использоваться несколькими исходными файлами, поскольку их фактические определения будут отсутствовать.

  • Если они не предназначены для повторного использования, укажите их определение (и, если необходимо, их прототип) в .c файле, где они должны использоваться.

Если GCC жалуется на невозможность встроить функцию из-за размера функции:

  • Спросите себя, действительно нужна ли эта функция для встраивания - по моему опыту, компилятор обычно знает лучше.

  • Если вы действительно хотите встроить эту функцию, always_inline атрибут функции может быть полезным. Возможно, вам также придется предоставить GCC параметр -finline-limit=n, отличный от установленного по умолчанию, увеличьте допустимый размер встроенных функций.

См. Также this для получения дополнительной информации о встроенных функциях и некоторых возможных подводных камнях, связанных с их использованием.

РЕДАКТИРОВАТЬ 2:

Если у вас есть функция static inline, определенная в файле общего заголовка, и вы хотите превратить ее в обычную, за неимением лучшего слова, функцию, вам следует:

  • Выберите .c файл, в котором наличие этой функции имеет смысл (т. Е. Поместите его вместе с другими связанными функциями).

  • Удалите ключевые слова static и inline из его определения и переместите определение из заголовка в этот файл.

  • Удалите ключевые слова static и inline из его прототипа и поместите его в файл заголовка.

Поздравляем, теперь у вас есть нормальная общедоступная функция.

Отказ от ответственности: вы только что создали функцию, которая была частной для ряда файлов, общедоступной для всей вашей программы. Если существует другой общедоступный символ - переменная или функция - с тем же именем, вы можете получить ошибки при связывании или даже странное поведение во время выполнения. Вас предупредили ...

person thkala    schedule 02.04.2011
comment
Спасибо за подробный ответ. На самом деле я не хочу встроить функцию. Поэтому, сохранив функциональность, я хотел бы удалить inline. Поскольку я определяю конкретную встроенную функцию в файле C, не стоит ли ключевое слово static перед функцией, создающей проблему? › - person thetna; 03.04.2011
comment
static в определении функции делает эту функцию закрытой только для этого .c файла. Если эта функция фактически не используется в этом .c файле, это мертвый код, поэтому компилятор жалуется. - person thkala; 03.04.2011

Объявите функцию обычно в файле заголовка

a.h

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

void function1(void);

#endif

Определите функцию в одном файле кода без static

a.c

#include "a.h"

void function1(void) {
  /* function definition */
}

и вызвать функцию из других файлов, после включения заголовка

b.c

#include "a.h"

void quux(void) {
  function1(); /* call regular function */
}

То, как вы делали это раньше (static и реализация в файле заголовка), работало, потому что каждый файл кода, который включал этот заголовок, имел свою собственную версию функции; отличается от любой другой функции с тем же именем в любом другом файле (но делает то же самое).

person pmg    schedule 02.04.2011
comment
Вы имеете в виду, что я не должен хранить прототип функции в самом заголовочном файле? Конкретный файл заголовка также включен в различные файлы C. Или это ключевое слово static имеет значение? - person thetna; 03.04.2011
comment
Заголовочный файл должен помочь другим файлам (единицам перевода) узнать правильный способ вызова функции. Если функция доступна только для одного файла .c (static), нет смысла добавлять прототип в файл .h. - person pmg; 03.04.2011
comment
Я просто хочу удалить ключевое слово inline, сохранив функциональность кода такой же, как и раньше. Что вы предлагаете в этом случае? Эти встроенные функции вызывались и в других файлах C. Разве в этом случае не требуется определять их в файле заголовка? - person thetna; 03.04.2011
comment
Тогда вы не можете объявить функцию static. Сохраните прототип в одном файле заголовка (a.h), определение в одном файле кода (a.c) и #include "a.h" в других файлах кода. - person pmg; 03.04.2011