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

Функция определена, но не используется предупреждение в C

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

 function XXXX defined but not used.

Но те функции XXXX, которые не используются в a.c, используются в b.c. Таким образом, я не могу полностью удалить эти функции. Итак, я решил создать отдельный файл, содержащий только те функции XXXX, и включил его везде, где он используется. В результате создается несколько файлов заголовков. Может ли кто-нибудь предложить мне эффективный способ решить эту проблему.

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

-Wno-unused-function

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

Ответ 3

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

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, ваше перемещение может отличаться от других компиляторов. Я не смотрел на выход asm, чтобы исследовать, когда почти неиспользованные функции лишены.

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

Ответ 4

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

Ответ 5

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

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