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

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

Единый код:

хиджры:

static __inline__ function1(){
    function definition;  
}

Я изменил:
хиджры:

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.

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

Ответ 1

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

Ответ 2

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

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

EDIT:

Обычно вам следует следовать следующим рекомендациям относительно встроенных функций:

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

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

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

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

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

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

ИЗМЕНИТЬ 2:

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

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

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

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

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

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

Ответ 3

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

хиджры

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