gcc warning: function used but not defined - c

I am getting the warning: function used but not defined. I have static
__inline__ in header file say a.h. The header file is included in a.c. I would like put all those inline function which are in header files into the .c files. Following code gives the idea of my problem.
Orginal code:
a.h:
static __inline__ function1(){
function definition;
}
I changed:
a.h:
static function1();
a.c:
#include "a.h"
static function1(){
function definition;
}
On doing above I got the warning:
warning: function function1 is used but not defined.
Could you please let me know why i am getting such warning? I would like to transfer all the __inline__ function into the .c so that I won't get the warning:
warning: function1 is could not be inlined, code size may grow.
Thanks in advance

You've declared the function to be static. This means that it is only visible within the current compilation unit. In other words: the implementation is only visible inside the a.c file. You need to remove the static keyword both in the a.h and a.c so that other .c files can see the function. You should specify a return value, e.g. void function1(); because it implicitly is int if you didn't specify one.

Functions declared static within a .c file are only visible/usable within that file only. If they are not used in it, then they are effectively dead code and the compiler warns you about this fact. In GCC you can use the unused function attribute to suppress this warning:
static int __attribute__((unused)) function1() {
...
}
EDIT:
In general you should usually follow the following guidelines regarding inline functions:
If they are used in multiple C files, declare them static and have their definition in an included header file. That allows all .c files that include that header to have their own private definition of the function, which allows the compiler to inline it. Lone static function prototypes make little to no sense in a header file that will be used by multiple source files, since their actual definitions will be missing.
If they are not intended to be reused, have their definition (and, if necessary, their prototype) in the .c file where they are supposed to be used.
If GCC complains about being unable to inline a function, due to the function size:
Ask yourself if you really need that function to be inlined - from my experience, the compiler usually knows best.
If you really, really want that function inlined, the always_inline function attribute may be of use. You may also have to provide a non-default -finline-limit=n option to GCC to increase the allowed size for inline functions.
See also this for additional information on inline functions and some possible pitfalls regarding their use.
EDIT 2:
If you have a static inline function defined in a shared header file and want to turn it into a normal, for lack of a better word, function you should:
Select a .c file where the presence of that function make sense (i.e. put it with other related functions).
Remove the static and inline keywords from its definition and move the definition from the header into that file.
Remove the static and inline keywords from its prototype and put it into the header file.
Congratulations, you now have a normal publicly-available function.
Disclaimer: you just made a function that was private to a number of files, public to all of your program. If there is another public symbol - variable or function - with the same name, you may get errors while linking or even strange behaviour at runtime. You've been warned...

Declare the function normally in the header file
a.h
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
void function1(void);
#endif
Define the function in a single code file with no static
a.c
#include "a.h"
void function1(void) {
/* function definition */
}
and call the function from other files, after including the header
b.c
#include "a.h"
void quux(void) {
function1(); /* call regular function */
}
The way you had before (static and implementation in header file) worked because each code file that included that header got its own version of the function; different to every other function of the same name in every other file (but doing exactly the same).

Related

Should I define functions in .h file or just declare them?

I'm new to C and I came across this statement:
"Functions need to be declared in .h files and not defined with exception of inline functions".
My question is then, where are standard functions defined?
"Functions need to be declared in .h files and not defined with exception of inline functions".
You declare the existence of a function in the header. For all dependents to see.
You implement (define) the function in the source file. Dependents cannot see this.
The header file is the API or your C file for use elsewhere in your application, hiding the implementation.
The exception for inline functions has to do with the fact that when compiling the dependent, the compiler must know what to put instead of the function call.
Functions for (private) use only inside your source file do not need to be declared in the header file. Why tell other code about it?
My question is then where are standard functions defined?
In the compiled library. You only know that they exist, not where they exist. The implementation is hidden from you. The linker connects the dots.
Yes functions are declared in .h file and they are defined in .c file
"Functions need to be declared in .h files and not defined with exception of inline functions"
Unknown Source
Unfortunately, this quote is ambiguous and not entirely correct as well.
Functions do not necessary need to be declared in .h files. You can declare a function in .c files as well, or even omit the declaration entirely (dependent upon your coding style and the place of the function definition).
Note for the latter, that the compiler reads a file from top to bottom.
For example, This is the content of the source file foo.c:
void foo (void)
{
// absolute foo / translated: It really does not make anything useful.
// this function is only to illustrate the omission of the prototype.
}
int main (void)
{
foo();
}
To call foo() we need no declaration of foo() at all because the definition is before its use in the source code (compiler reads from top to bottom).
Would it be behind, we would need a declaration to tell the compiler what foo() is, f.e.:
void foo (void); // foo() needs to be declared. Else the compiler does not know
// what foo is when foo is called in main.
int main (void)
{
foo();
}
void foo (void)
{
// absolute foo.
}
It is just a common use to place the declaration/ prototype of a function in a separate header, but you actually do not need to do so. This is the header version:
foo.c:
#include "foo.h" // We need to include the header to gain the prototype.
// Note that `foo.h` needs to be in the same directory
// as `foo.c` in this case. Else you need to specify the
// full path to foo.h .
int main (void)
{
foo();
}
void foo (void)
{
// absolute foo.
}
foo.h:
void foo (void);
What the quote really means is:
A function definitely should not be defined in an .h file (as these are headers, not source files), with the only exception of inline functions, which indeed can be defined in .h files.
"My question is then, where are standard functions defined?"
That is a completely different question and implementation-specific. The functions are stored in an either fully or semi-compiled form. I can not answer it here without the focus to any specific implementation (OS, compiler).

If function declaration is not in header file, is static keyword necessary?

If a function declaration isn't in a header file (.h), but is instead only in a source file (.c), why would you need to use the static keyword? Surely, if you only declare it in a .c file, it isn't seen by other files, as you're not supposed to #include .c files, right?
I have already read quite a few questions and answers about this (eg. here and here), but can't quite get my head around it.
What static does is make it impossible to declare and call a function in other modules, whether through a header file or not.
Recall that header file inclusion in C is just textual substitution:
// bar.c
#include "header.h"
int bar()
{
return foo() + foo();
}
// header.h
int foo(void);
gets preprocessed to become
int foo(void);
int bar()
{
return foo() + foo();
}
In fact, you can do away with header.h and just write bar.c this way in the first place. Similarly, the definition for foo does not need to include the header in either case; including it just adds a check that the definition and declaration for foo are consistent.
But if you were to change the implementation of foo to
static int foo()
{
// whatever
return 42;
}
then the declaration of foo would cease to work, in modules and in header files (since header files just get substituted into modules). Or actually, the declaration still "works", but it stops referring to your foo function and the linker will complain about that when you try to call foo.
The main reason to use static is to prevent linker clashes: even if foo and bar were in the same module and nothing outside the module called foo, if it weren't static, it would still clash with any other non-static function called foo. The second reason is optimization: when a function is static, the compiler knows exactly which parts of the program call it and with what arguments, so it can perform constant-folding, dead code elimination and/or inlining.
The static keyword reduces the visibility of a function to the file scope. That means that you can't locally declare the function in other units and use it since the linker does not add it to the global symbol table. This also means that you can use the name in other units too (you may have a static void testOutput(); in every file, that is not possible if the static is omitted.)
As a rule of thumb you should keep the visibility of symbols as limited es possible. So if you do not need the routine outside (and it is not part of some interface) then keep it static.
It allows you to have functions with identical names in different source files, since the compiler adds an implicit prefix to the name of every static function (based on the name of the file in which the function is located), thus preventing multiple-definition linkage errors.
It helps whoever maintains the code to know that the function is not exposed as part of the interface, and is used only internally within the file (a non-static function can be used in other source files even if it's not declared in any header file, using the extern keyword).

Multiple header files to one source file?

I have a source file called source.c and a public header file called source.h. The source.c contain s
#include "source.h"
I do not want all the functions in source.c to be public, therefore I want another header file called priv_source.h that refers to some private functions in source.c.
Do the compiler understand that priv_source.h also is a header file to source.c or do I have to make another c-file called priv_source.c?
Do the compiler understand that priv_source.h also is a header file to source.c or do I have to make another c-file called priv_source.c?
C compiler does not make any such connection: all files, headers and sources, are unrelated to the compiler. All it knows is the name(s) of the translation units that it needs to process (i.e. the names of your .c files) and the names of headers that these translation units include.
It is common to split declarations in two parts - the public and the private ones. In such cases, however, the private header would include the public one, like this:
source.h
// Public declarations go here
void public_function1(int, int);
void public_function2(int, double, int);
priv_source.h
#include "source.h"
void private_function1(float);
void private_function2(char*);
source.c
#include "priv_source.h"
There are two points in your question:
Function declarations are put into header files so that they can be
included into multiple source files, without explicit need to
declare in each and every source file. So, only put those declaration in header file which you WANT to be available to other files as well.
If some function need to be restricted to a particular file, make
that function definition as static. Once you define a function as
static, it will not be visible from outside for linking. The scope
of that function will be limited to the same compilation unit,
usually that file only.
In c by default all function are public means a function declare inside any header can be used by other method if that function simply include the header. Now if you explicitly declare a function like static return_type name(some arguments may or may not) then this can't be access out side of that file. Now there is no such privilege to hide any function like java, c++ and c# etc. May be this can be I am not sure can be achieve by using #if #elseif and #endif statement. You have to write logic if you that function present in your code then put in #if. Because in #if statement if condition is not satisfy then after preprocessor stage that part will vanish from our code similar to comments in our code. See I am not sure but may be.
Thanks
asif aftab

Is there a way to have static prototypes AND public ones in the same header file in C?

The compiler will always whine when I have mixed public with static prototypes in a header file.
Say I have header main.h with a static prototype for function a and a normal prototype for function b. Then I want to #include the header in two .c files, namely main.c and other.c. In main.c I need an include as I call the function before any prototype.
main.h:
static int a(void);
int b(void);
main.c:
#include "main.h"
void main(){
a();
}
static int a(void){
/* do stuff */
}
int b(void){
/* do stuff */
}
other.c:
#include "main.h"
b();
What's the best practice for this than the obvious solution of splitting the header file into a seperate header exclusively for static prototypes and one for public ones?
You don't put declarations of static functions in header files. Since they are local to the .c file that defines them, it doesn't make sense to export them from a header file.
There are two things you can do:
Define the function before it is called in the c file (move definition of a() above main).
Declare static function at the top of the C file (this is my personal choice). In your case, you move the declaration of a() to the top of main.c.
If the function is going to be used in multiple translation units, then you can define the static function in the header file. It could usefully be inline instead of static assuming you have a grown-up compiler that supports C99.
It makes no sense having static prototypes in a header, the reason for this is that static functions have file scope so no module outside can anyway access the functions.
Instead I would suggest you put static prototypes only in the .c file at the top of the file in the same file they are defined.
If you have the declaration of b() in main.h, why do you need it again in other.c that includes it? Other than that, it's all good, can't see any issue.
The important point to keep in mind about the "normal" functions is that all the forward declarations of the same function (b() in this case) must match, otherwise you'll have trouble (linking errors, compiler errors, what's not). In your case they don't match.
Unless of course b(); is an actual call to the function, but at least in the code you posted its out of any scope, thus is treated as a forward declaration.
Re the static forward declarations, they limit the visibility of the function to the compilation unit. So calling a() in other.c will not execute the a() implemented in main.c. That's the whole point of static in C.
IF the "static" function you want to define is short enough or cheap enough, you'll better define it as static inline and put its definition with its body (not only its declaration) in the *.h header file.

How to declare an inline function in C99 multi-file project?

I want to define an inline function in a project, compiled with c99. How can I do it?
When I declare the function in a header file and give the detail in a .c file, the definition isn't recognized by other files. When I put the explicit function in a header file, I have a problem because all .o files who use it have a copy of the definition, so the linker gives me a "multiple definition" error.
What I am trying to do is something like:
header.h
inline void func()
{
do things...
}
lib1.c
#include "header.h"
...
lib2.c
#include "header.h"
with a utility which uses both lib1.o and lib2.o
Unfortunately not all compilers are completely complying to C99 in that point even if they claim that they'd be.
An conforming way to do this is
// header file. an inline definition alone is
// not supposed to generate an external symbol
inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);
Newer versions of gcc, e.g, will work fine with that.
You may get away with it for other compilers (pretenders) by defining something like
#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);
Edit:
compilers with C99 support (usually option -std=c99) that I know of
gcc (versions >= 4.3 IIRC) implements
the correct inline model
pcc is also correct
ggc < 4.3 needs a special option to
implement the correct model,
otherwise they use their own model
that results in multiple defined
symbols if you are not careful
icc just emits symbols in every unit
if you don't take special care. But
these symbols are "weak" symbols, so
they don't generate a conflict. They
just blow up your code.
opencc, AFAIR, follows the old gcc specific model
clang doesn't emit symbols for inline functions at all, unless you have an extern declaration and you use the function pointer in one compilation unit.
tcc just ignores the inline keyword
If used by itself, in C99 inline requires that the function be defined in the same translation unit as it's being used (so, if you use it in lib1.c, it must be defined in lib1.c).
You can also declare a method as static inline (and put the definition in a header file shared between two source files). This avoids the multiple-definition issue, and lets the compiler inline the file across all the translation units where it's used (which it may or may not be able to do if you just declare the function in one translation unit).
See: http://www.greenend.org.uk/rjk/2003/03/inline.html
I think you don't need to use the inline word when you are defining and declaring the function inside the Header file, the compiler usually takes it as inline by default unless it's too long, in which case it will be smart enough to treat it as a normal function.
I think the multiple definition may be caused by the lack of a Include Guard in the Header file.
You should use something like this in the header:
#ifndef HEADERNAME_H
#define HEADERNAME_H
void func()
{
// do things...
}
#endif

Resources