I have the following code layout
header.h
#ifndef _header_h
#define _header_h
void empty(float *array, int l)
{
int i;
for (i=1 ; i<=l ; i++)
{
array[i]=0;
}
}
#endif
and two files (lets call them file1.c and file2.c)
#include "header.h"
void function/*1 or 2*/(){
....
empty(a,b);
....
}
So compiling works fine but the linker command fails as the compiler says that there is a duplicate function definition. How can I avoid that with still using the header file? It is working fine when I only define the function in the header and create another .c file containing the full function. I always thought declaring it in the header is the way to go.
I always thought declaring it in the header is the way to go.
Yes, it is. Declaring it in the header is fine. It is not any good to define it in a header, though. (unless it's static inline, but you probably don't want to do that these days.)
You should never have things in a header that require memory in the running program. This is a rough way of specifying it, but it works pretty well in practice.
In other words, the header should only have the prototype for the function, which is a compile-time thing that doesn't "exist" in the running program (unlike the code of the function itself, which of course exists at runtime):
void empty(float *array, int l);
Then put the code in a separate C file, which you compile and link separately.
You have the function empty defined as a global symbol in the header. This means it will be a visible symbol in all compilation units that include it. There are three general workarounds:
make it a static function
static void empty(...) {...}
put the implementation into a separate compilation unit
in header.h:
void empty(float *array, int l);
in empty.c implement it
instruct your linker to ignore duplicate symbols. This differs from linker to linker, consult man ld.
On OS X: -m flag.
On Linux: -z muldefs
Related
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 I have a c project where my main program needs file1 and file2 but file2 also needs file1. Is there a way I can get around including file2 in both main and file1? If I have an include guard, will this prevent file1.c from being added twice?
//file1.h
#ifndef FILE1_H
#define FILE1_H
void func1(void);
#endif
--
//file1.c
#include "file1.h"
void func1(void) {
..do something
}
--
//file2.h
#ifndef FILE2_H
#define FILE2_H
void func2(void);
#endif
--
//file2.c
#include "file2.h"
#include "file1.h"
void func2(void) {
..do something
func1();
}
--
//main.c
#include "file1.h"
#include "file2.h"
int main(void) {
func1();
func2();
return 0;
}
-- Since file2 includes file1, can I do this? will it prevent repetition of file1 code?
//main.c (alternate)
#include "file2.h"
int main(void) {
func1();
func2();
return 0;
}
I'm not too concerned about problems arising if file2 decides to no longer include file1 in the future. I'm much more concerned with wasted space.
What I'd like to know is A: does the include guard prevent the code duplication and if so, there is no additional space used by including file1 in both main.c and file2.c. B: in the case that extra space is being used, will my alternate main.c work?
Quick explanation (with the note that all of this can be overwritten by people that know what they are doing):
First of all, two definitions: declaration is when you write down that something exists. For example, "int foo();" or "struct bar;". Note that we can't actually use this thing yet, we've just given it a name. As long as you declare them as the same thing, you can declare things as many times as you want! (variable declaration has its own rules).
Anything you want to use needs to be declared before you reference it.
definition is when you say what the declaration is. int foo() {asdfadf;} or struct bar{int x;}. Things can be (and often are) defined when they are declared, but not always.
In C, you must follow the One Definition Rule. Things can be declared as often as you like, but they can be only defined once per translation unit (defined in one sec). (in addition, function calls can only be declared once per entire executable).
There are very few things that need to be defined before you use them...other than variables, you only need to define a struct before you use it in a context where you need its size or access to its members.
What is a translation unit? It is all the files used to compile a single source file. Your header files aren't targeted for compilation. Only your .c files (called "source files") are. For each c file, we have the idea of a "translation unit", which is all the files that are used to compile that c file. The ultimate output of that code is a .o file. A .o files contains all the symbols required to run the code defined in that c++ file. So your c file and any files included are withing the header file. Note: not everything declared in the translation unit needs to be defined in it to get a valid .o file.
So what is in a header file? Well (in general) you have a few things:
function declarations
global definitions & declarations
struct definitions & declarations
Basically, you have the bare bones declarations and definitions that need to be shared between the translation units. #include allows you to keep this in one shared file, rather than copying and pasting this code all over.
Your definitions can only happen once, so a include guard prevents that from being a problem. But if you only have declarations, you don't technically need and include guard. (You should still use them anyway, they can limit the cross-includes you do, as well as work as a guarantee against infinitely recursive inclusion). However, you do need to include all declarations relative to each translation unit, so you will most likely include it multiple times. THIS IS OK. At-least the declaration is in one file.
When you compile a .o file, the compiler checks that you followed the one definition rule, as well as all your syntax is correct. This is why you'll get these types of errors in "creating .o" steps of compilation.
So in your example, after we compile, we get file1.o (containing the definition of func1), file2.o (containing the definition of func2), and main.o (containing the definition of main). The next step is to link all these files together, using the linker. When we do, the compiler takes all these .o files, and makes sure that there is only one definition for each function symbol in the file. This is where the magic of letting main.o know what is in file1.o and file2.o happens: it resolves the "unresolved symbols" and detects when there are conflicting symbols.
Final Thought:
Keeping code short is kindof a misguided task. You want your code to be maintainable and readable, and making the code as short as possible is about the opposite of that. I can write a whole program on one line with only single letter alpha-numberic variables names, but no one would ever know what it did...what you want to avoid is code duplication in things like declarations. Maintaining a long list of #includes can become tricky, so it is often good to group related functions together (A good rule of thumb is that if I almost always use A and B together) then they should probably be in the same header file.
Another thing I occasionally (occasionally because it has some serious drawbacks) is to use a convenience header file:
//convience.h
#ifndef CONVIENIENCE_H
#define CONVIENIENCE_H
#include "file1.h"
#include "file2.h"
#endif
The convenience header file only has other header files in it, which ensures that it NEVER contains code, which makes it a little easier to maintain, but still kindof a mess. Also note that if you do the include guards in file1 and file2, the convienience guard isn't nessisary, though it can (theoretically) speed up compilation.
Why can't you have a single header where you can put both your functions func1() and func2().
Just include the header in different files.
Didn't get what you mean by code duplication.
//file1.h
extern void func1();
extern void func2();
//file1.c
#include<file1.h>
void func1()
{`
enter code here`
}
//file2.c
#include<file1.h>
void func2()
{
}
//main.c
#include <file1.h>
main()
{
func1();
func2();
}
So I am doing some work in C where I have implementation of the same function in both assembly and C and I want to compare the performance of C vs assembly implementation. Now for that I would want to be able to compile and call the function conditionally i.e I would want to create a function which would act as an interface between the caller and the right function that I want to call. somehow I am not sure how to do that.
I was thinking somewhere along the line of following:
//header file containing the C definition and the assembly definition
void getstate(state* m, int* values);
extern void kalmanstate(state* m, int* values);
Then the caller can include the above header file and pass either &getstate or &kalmanstate.
void callTheRightFunction(state* m, int* values, void *fnptr(state*,int*))
{
*fnptr(m,values);
}
However the problem with this is that both getstate and kalmanstate will be compiled which kind of defeats the purpose of my simulation. It does not sound to me the best implementation of the wrapper I want to have. I know conditional execution exists in C but how would I use it to get the right function compile? I mean if I do something like this in the header file:
#ifdef __C__FUNC
void getstate(state* m, int *values);
#endif
#ifdef __kalman
void kalmanstate(state *m, int *values)
#endif
Then in the caller:
include "headerfile.h" //include the above header file
//caller defining _C_FUNC
define __C_FUNC
callTheRightFunction(m,p,&getstate);
But since I include the header file at the beginning when none of them are defined it would probably not include any of them at all and thus will generate runtime errro.
Any suggestions towards right direction would be appreciated. Thanks in advance guys!
Based on your addition to the original question, you were wondering if none of the functions would be compiled. Then you'll have to define __C__FUNC or __kalman before you include the header file:
#define __C__FUNC
#include "header.h"
But to avoid this problem when you don't define anything, an approach would be for you to use just one definition, like this, on the SOURCE file:
#ifdef __GSTATE_USE_C_FUNCTION
void getstate(state* m, int *values)
{
// C version
}
#else
void getstate(state *m, int *values)
{
// Assembly version
}
#endif
And on the header file:
void getstate(state *m, int *values);
(Note the same function name, so you don't need to modify the code when you're calling the function)
But this would only work if you're including the header on the source file where getstate is being implemented too. (*1)
Then if you forgot to define __GSTATE_USE_C_FUNCTION before your header inclusion, the second function would be used, because it triggered the #else.
Now, you'd use it like this on a header file that BOTH source files include (that is, the file that implements the function, and the file that uses it):
// Comment the line below if you want the other version
#define __GSTATE_USE_C_FUNCTION
Of course you'd have to include this header before including the header which contains the prototype declaration.
And on the source file:
// Somewhere else on the code where you use the function
getstate(m, values);
So you'd only have to change the #define line on the global header.
In addition, if your compiler has an option to do preprocessor defining in the command line for it, then you'd not even need to define __GSTATE_USE_C_FUNCTION before the #include, you'd just use as a command line option, something like this (for example in bcc32):
bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c
This would avoid the problem (*1), and you'd not have to make a global header file that both source files have to include.
I see no problem here.
Options:
name the ASM and C functions that do the same differently. Use if or switch or, god forbid, ?: to call the right one.
Same name setup as above. Use a function pointer. If you assign it the address of the ASM function, then function calls through this pointer will go there. If you assign it the address of the C function, the calls will similarly go to the C function.
Same name setup as above. Define a macro that would expand to either the ASM or the C function's name. You can define the macro at compile time using the compiler's options. Use that macro in the code that needs to call one of the two functions.
Place the ASM and C functions into separate .asm/.s and .c files. When compiling either include one file in the list of compiled files or include the other.
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).
#include <stdio.h>
#include <stdio.h>
int main ()
{
printf ("hello world");
return 0;
}
when I compile this, the compiler doesn't give any warning/error for including stdio.h twice. Why is it so? Aren't the functions scanf, printf etc. declared and defined twice now?
Thanks, in advance
Typically, header files are written similar to the below example to prevent this problem:
#ifndef MYHEADER
#define MYHEADER
...
#endif
Then, if included more than once, then 2nd instance skips the content.
In addition to the use of include guards, as pointed out by Mark Tolonen's answer, there is no problem with declaring a function more than once, as long as the declarations are compatible. This is perfectly fine:
int foo(int, char *);
int foo(int a, char *p);
extern int foo(int x, char y[]);
In fact, since every definition is also a declaration, whenever you "forward-declare" a function declared in the same file, you are declaring the function twice.
What is not OK is to create multiple external definitions of a function; but well-written header files should not create external definitions - only declarations. The (single) definition of the printf and scanf functions should be in an object file, which is linked with your program when it is built.
No, the header files usually define a flag and then use #ifndef to include themselves only if the flag was undefined.
Open one up and see.
As an aside, doing the "#ifndef" trick is appropriate for headers used by other people (like the standard headers).
If you need the #ifndef for a "private" program, then you are doing it "wrong". That is, you can and should organize headers within a project so they are not included more than once.
One reason that this is helpful is that keeps headers you think you have deleted from popping up again.
Since you can't control how public headers are used, this trick is reasonable for public headers. This trick is completely unnecessary for private headers.