Функция определена, но не используется предупреждение в C - PullRequest
30 голосов
/ 17 мая 2010

У меня есть несколько исходных файлов на C (файлы .c и .h).Заголовочные файлы содержат ряд функций.Из этих функций только частично используются в исходном файле .C. Предположим, что ах, bh - файлы заголовков, а ac и bc - файлы .c.ах включен в переменную, но только ряд функций, которые в.h используются, а остальные не используются.После компиляции я нахожу следующие предупреждения:

 function XXXX defined but not used.

Но те функции XXXX, которые не используются в ac, используются в bc. Поэтому я не могу полностью удалить и эти функции.Итак, я решил создать отдельный файл, содержащий только эти функции XXXX, и включал его везде, где он используется. При этом создается несколько файлов заголовочных файлов.Кто-нибудь может предложить мне какой-нибудь эффективный способ решить эту проблему.

Ответы [ 5 ]

68 голосов
/ 17 мая 2010

Предупреждение «Функция определена, но не используется» выдается только для функций с внутренней связью , то есть функциями, которые объявлены как static. Эти функции доступны только в одном модуле перевода, поэтому компилятор всегда знает, используются ли они (в программе) или нет. Если вы не ссылаетесь на эти функции в их единице перевода, эти функции, как известно, не используются, и генерируется предупреждение.

Вы говорите, что эти функции "не используются в a.c, но используются в b.c". Это неправда. Когда вы объявляете (и определяете) функцию как static в заголовочном файле, каждая единица перевода, которая включает этот заголовочный файл, получает свою собственную внутреннюю копию функции. Несмотря на то, что эти функции выглядят абсолютно одинаково, они все еще являются отдельными, полностью независимыми функциями. Тот факт, что они имеют одинаковое имя и состоят из одного и того же кода, ничего не значит для компилятора. Итак, в b.c вы получили полностью независимую копию функции, которая используется (как вы говорите), но полностью независимая копия в a.c все еще не используется.

Вопрос в этом случае: почему вы это делаете. С какой стати вы определяете статические функции в заголовочном файле? Если вам действительно нужно это сделать (т. Е. Если вы действительно хотите порождать отдельный внутренний «клон» этой функции в каждом модуле перевода), вы можете обойти предупреждение, используя некоторые специфичные для компилятора средства. Как и в GCC, например, вы можете объявить функцию с помощью __attribute__((unused)), и предупреждение для этой функции больше не будет выдаваться.

Но обычно не требуется определять функции в заголовочном файле. Обычно можно использовать функцию с внешней связью (т.е. без static), определить ее в одном из файлов .c и поместить объявление (прототип) в заголовочный файл. В этом случае компилятор не выдаст никаких предупреждений, даже если функция объявлена, но не используется в каком-либо модуле перевода.

8 голосов
/ 16 января 2015

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

static int get_version_number(void) { return 42; }
static double hidden_global_variable(void) { return 3.14; }
static int potential_alternative_to_macro(int x) { return 4 * x; } 

Напишите другую функцию, вероятно, на основе имени файла заголовка,

static void wno_unused_myheadername(void)
{
  /* don't need to actually call the functions to avoid the warnings */
  (void)&get_version_number;
  (void)&hidden_global_variable;
  (void)&potential_alternative_to_macro;
  return;
 }

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

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

Я проверил, что вышеизложенное удаляет предупреждения, как и ожидалось, в clang и gcc, ваш milage может отличаться в зависимости от других компиляторов. Я не смотрел на вывод asm, чтобы выяснить, когда удаляются почти неиспользуемые функции.

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

8 голосов
/ 17 мая 2010

Если вы просто хотите скрыть предупреждение, используйте:

-Wno-unused-function

Однако вам, вероятно, следует следовать совету caf ответ . Похоже, вы определили функцию, когда хотели добавить только ее объявление.

5 голосов
/ 25 апреля 2014

Другая возможность - определить эти функции как inline вместо static. В этом случае они должны быть определены в заголовке, чтобы определение было видно везде, где они вызываются.

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

5 голосов
/ 17 мая 2010

Похоже, ваша проблема в том, что вы определяете функции в .h файлах. Не делай этого. Вместо этого просто поместите свои декларации в .h файл и получите соответствующий .c файл, содержащий определения функций:

common.h:

#ifndef _COMMON_H
#define _COMMON_H

int foo(int a, int b);

int bar(double x, double y, double z);

#endif /* _COMMON_H */

common.c:

#include "common.h"

int foo(int a, int b)
{
    /* code */
}

int bar(double x, double y, double z)
{
    /* code */
}

Тогда ваши a.c и b.c должны #include "common.h", и вам нужно договориться о том, чтобы common.c скомпилировали в полную программу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...