43

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.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
thetna
  • 6,903
  • 26
  • 79
  • 113
  • This isn't a problem for me. There must be something strange about your function declarations or how you are compiling. Can you give more detail? – crazyscot May 16 '10 at 22:34
  • 2
    I think we need to see some of the code as this does not happen normally - see standard headers for examples – mmmmmm May 16 '10 at 22:35
  • 4
    There is not such thing as stupid warning. – vladv May 16 '10 at 22:40
  • possible duplicate of [hide defined but not used warning with gcc?](http://stackoverflow.com/questions/386220/hide-defined-but-not-used-warning-with-gcc) – thomasrutter May 16 '10 at 22:42
  • Not duplicate of that question. I'd say that this question is not really about *hiding* the warnings, but rather about eliminating the actual reason behind these warnings. – AnT stands with Russia May 17 '10 at 01:07

6 Answers6

93

"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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Doing this is useful for creating libraries when one function is a translation to another to give more meaning to it, such as `static bool CanHazCheezBurger() { return flags & (HAZCHEEZ | HAZBURGER) }`. Its a try to inline it, but it fails because there's no inlining, only copying. – Leonardo Jun 14 '14 at 23:06
  • Actually there are other reasons why this might be something you cannot just remove. There are cases where a common macro is used from a library, which defines multiple static functions, but not all of those functions will be used. This is part of the reason we see this type of warning, so there us no simple solution without making a lot of changing to hide a warning. It's also unfortunate that __attribute__ seems to be the recommended solution, as it's not portable. –  Sep 24 '19 at 06:30
  • I have heard that it can be useful to define a static function within a header file so that the compiler can inline the function (since it is more difficult for compilers to inline external functions). However, as compilers get better, I am not sure whether this is necessary anymore. – DBear Oct 26 '21 at 01:42
  • When you say external linkage, do you mean one should typically use the `extern` keyword for functions in headers? – user18348324 Feb 20 '23 at 09:35
10

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.

Jon Chesterfield
  • 2,251
  • 1
  • 20
  • 30
9

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.

Community
  • 1
  • 1
thomasrutter
  • 114,488
  • 30
  • 148
  • 167
  • 3
    From my reading, I would guess that these warnings are very valid and should not be hidden. I think Andrey and caf are correct in that the OP is defining static functions in .h files. Simply hiding these warnings will not be helpful; chances are that this will cause larger problems down the road. – mbauman May 17 '10 at 01:23
  • You're right, I think that caf's answer above is probably correct. http://stackoverflow.com/questions/2845748/function-defined-but-not-used-warning-in-c/2846030#2846030 I've edited mine now. – thomasrutter May 17 '10 at 05:18
  • I'm using cgo to make a wrapper and knowing this flag is useful. – Etienne Gautier Apr 22 '19 at 11:40
8

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.

Community
  • 1
  • 1
coombe
  • 111
  • 1
  • 4
  • I thought the inline keyword is only a suggestion to the compiler? – Michael Apr 13 '17 at 08:20
  • 1
    @Michael yes and no. Regarding actually inlining the function, `inline` is only a suggestion. However, in C99, a function defined with `inline` and without `extern` will **never** be exported from the translation module. In other words, `inline` enforces `static`. However, for all I know it still mutes the warning - `static` and `static inline` can trigger the unused warning, `inline` alone will not. – Eph Oct 28 '20 at 09:18
4

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.

caf
  • 233,326
  • 40
  • 323
  • 462
  • this doesn't answer the question. moreover it doesn't explain why one shouldn't define functions in headers. moreover there are valid reasons for doing so. – johannes_lalala Mar 29 '22 at 21:41
  • @johannes_lalala: The question seems to be *" Can anybody please suggest me to some effective way to solve this problem."* which I believe I've answered. – caf Mar 30 '22 at 22:09
-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.

tlr
  • 1
  • 1
    Please check [Help Center](https://stackoverflow.com/help/how-to-answer) for how to write a good answer. If you want to comment about another answer, please add a comment, not another answer. – Jean Marcos Oct 31 '19 at 20:18