thetna
thetna

Reputation: 7143

Function defined but not used warning in C

I have a number of C source files(both .c and .h files). header files contains a number of functions. Out of those functions, only partially are used in a source .C file.Suppose a.h,b.h are header files and a.c and b.c are .c files. a.h is included in a.c. But only a number of functions those are in a. h are used and rest are not used. After compilation I find following warnings:

 function XXXX defined but not used.

But those XXXX functions which are not used in a.c are used in b.c. So, i can't completely remove those functions too. So , i decided to make a separate file containing only those XXXX functions and included it wherever it is used.Doing this is creating multiple number of header files. Can anybody please suggest me to some effective way to solve this problem.

Upvotes: 46

Views: 116844

Answers (6)

tlr
tlr

Reputation: 1

No one seems to be mentioning that static function definitions in .h files make very good typed macros in C. I think that is a very valid way to use this type of construct but then it needs to be made warning free of course.

The common.c/common.h solution suggestion by caf will work around such a warning but instead generate a function call for each instance of the function which you may not want.

Upvotes: -1

Jon Chesterfield
Jon Chesterfield

Reputation: 2341

As an alternative to "don't do that", consider the following - a set of functions that will trigger up to three unused function warnings.

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; } 

Write another function, probably based on the name of the header file,

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;
 }

We're now down to one unused function warning. If you add a call to wno_unused_myheadername() in any of the extern functions declared in the file that includes the header, the whole set of unused function warnings will disappear. Since they're now all used.

The compiler will strip out anywhere from all to none of the unused functions, including the wno_unused_myheadername, since it can see all of the definitions and can probably determine that the single call to the wno_unused function doesn't actually do anything.

I've checked that the above removes the warnings as expected under clang and gcc, your milage may vary with other compilers. I haven't looked at the asm output to investigate when the nearly-unused functions are stripped.

As for why - a good reason would be using a lot of small functions which are well suited to inlining in C89, which doesn't have the inline keyword, without requiring link time optimisation from your compiler.

Upvotes: 10

coombe
coombe

Reputation: 111

Another possibility is to define these functions as inline instead of static. In this case, they are required to be defined in the header so that the definition is visible everywhere they are called.

The compiler will inline the code in each place that the function is used, so be careful that this is what you really want. Here's an answer with a nice discussion of these tradeoffs.

Upvotes: 8

AnT stands with Russia
AnT stands with Russia

Reputation: 320391

"Function defined but not used" warning is only issued for functions with internal linkage, i.e. functions that are declared as static. These functions are only accessible in one translation unit, so the compiler always knows whether they are used (in the program) or not. If you don't reference these functions in their translation unit, these functions are known to be unused, and the warning is generated.

You are saying that these functions "are not used in a.c, but used in b.c". This is not true. When you declare (and define) a function as static in the header file, each translation unit that includes that header file gets its own internal copy of the function. Even though these functions look absolutely the same, they are still separate, completely independent functions. The fact that they have the same name and consist of the same code means nothing to the compiler. So, in b.c you got a completely independent copy of the function, which is used (as you say), but the completely independent copy in a.c is still not used.

The question in this case is why you are doing this. Why on Earth are you defining static functions in the header file? If you really need to do this (i.e. if you really want to spawn a separate internal "clone" of this function in each translation unit), you can work around the warning by using some compiler-specific means. Like in GCC, for example, you can declare the function with __attribute__((unused)) an the warning for this function will no longer be issued.

But normally one wouldn't need to define functions in the header file. Normally one'd use a function with external linkage (i.e. no static), define it in one of the .c files and put the declaration (prototype) in the header file. The compiler will not issue any warnings in this case, even if the function is declared but not used in some translation unit.

Upvotes: 97

thomasrutter
thomasrutter

Reputation: 117333

If you just want to hide the warning, use:

-Wno-unused-function

However, you should probably follow the advice in caf's answer instead. It sounds like you may have defined a function when you only meant to add its declaration.

Upvotes: 9

caf
caf

Reputation: 239011

It sounds like your problem is that you're defining functions in .h files. Don't do that. Instead, just put your declarations in the .h file, and have a matching .c file that contains the function definitions:

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 */
}

Then your a.c and b.c should #include "common.h", and you'll need to arrange to have common.c compiled into the complete program.

Upvotes: 4

Related Questions