Reputation:
Let's suppose that I write some functions in a file, that we'll call foo.c
.
This is foo.c
:
int d;
typedef int bar;
int foo(int a, int b){
...
}
void boo(){
...
}
char *test(){
...
}
Now, boo is a function used only inside foo.c, while foo()
, test()
, d
, and Bool
will need to be able to get called inside other files.
In order to do that, I know that I have to create a foo.h
file and write it like this:
extern int d;
extern typedef int bar;
int foo(int a, int b);
char *test();
then #include "foo.h"
in the foo.c
file, and whenever I want to use the types and functions defined in foo.c, I have to include both foo.h
and foo.c
in the file in which I wanna use foo.c functions and types.
So foo.c
in the end would look like this:
#include "foo.h"
int d;
typedef int bar;
int foo(int a, int b){
...
}
void boo(){
...
}
char *test(){
...
}
Here are my questions.
Q1. Is this how you actually do it? Since foo.h
is already included in foo.c
, wouldn't it be sufficient to include only foo.c
in the file in which I want to use its functions? Can't I just directly define the functions inside of the foo.c file, not using the foo.h file at all?
Q2. Do you actually have to put the extern
in front of typedefs in the foo.h
file?
Q3. Let's say that in foo.c
I use some standard C libraries like string.h and math.h . Where should I include them? Directly in the foo.c
file, in the foo.h
file or in both? Are #ifndef
instructions necessary? If so, how do you use them correctly?
Q4. After writing the foo.c
and foo.h
file, am I all ready to go? Like, I don't need to compile them or anything, right? I can just #include
them wherever I need just like that?
Q5. Somewhere else I've read that if I want to use a custom library these are the steps that I need to follow:
foo.h
)foo.c
#include ing foo.h
gcc -o foo.o -c foo.c
foo.h
in the program in which I want to use foo.c
functionsgcc my_proj.c foo.o
Are these steps actually necessary? Because I haven't seen them mentioned anywhere else. Why do I only need to include foo.h
in the file in which I want to use foo.c
functions? What exactly is an object file?
Thanks for your time and sorry if this is a bit lengthy
Upvotes: 0
Views: 66
Reputation: 4527
Q1. Is this how you actually do it?
No
Since foo.h is already included in foo.c, wouldn't it be sufficient to include only foo.c in the file in which I want to use its functions?
You should only include .h
files; both in the file that defines them, and in the ones that use them. As an extra, that include should be the first one in the file that defines the functions, but in the files that use them, it should go after the rest (standard headers, other packages' headers, ...); the reason for this is to detect errors easily.
Can't I just directly define the functions inside of the foo.c file, not using the foo.h file at all?
Usually, no. Only static inline
functions should do that.
Q2. Do you actually have to put the extern in front of typedefs in the foo.h file?
No: typedef int foobar_t;
Q3. Let's say that in foo.c I use some standard C libraries like string.h and math.h . Where should I include them?
In the file that needs them (foo.c
). Include in every file only the headers that it needs. No more; no less.
Directly in the foo.c file, in the foo.h file or in both?
foo.c
Are #ifndefinstructions necessary? If so, how do you use them correctly?
Yes:
// foo.h
#ifndef FOO_H
#define FOO_H
Here go all the contents of foo.h
#endif /* foo.h */
Q4. After writing the foo.c and foo.h file, am I all ready to go? Like, I don't need to compile them or anything, right? I can just #include them wherever I need just like that?
You need to compile foo.c
into foo.o
(object file) and then you probably would like to do a static library (.a
) or a dynamic one. You can include it wherever you want, but you will need to prepare your Makefile to do so.
Q5. Somewhere else I've read that if I want to use a custom library these are the steps that I need to follow:
define the interface (foo.h)
write foo.c #include ing foo.h
creating an object file like this gcc -o foo.o -c foo.c
including foo.h in the program in which I want to use foo.c functions
linking the object file like this gcc my_proj.c foo.o
Are these steps actually necessary?
Yes
Because I haven't seen them mentioned anywhere else. Why do I only need to include foo.h in the file in which I want to use foo.c functions?
Read more about compiling and linking.
What exactly is an object file?
A compiled file. Many of them are usually linked together to produce the executable file.
Upvotes: 1
Reputation: 91017
Q1. Is this how you actually do it? Since foo.h is already included in foo.c, wouldn't it be sufficient to include only foo.c in the file in which I want to use its functions?
You just don't include .c files. In your case, foo.c and the other files are separate compilation units which get linked together in the end.
Q2. Do you actually have to put the external in front of typedefs in the foo.h file?
No, typedefs don't need extern
.
Q3. Let's say that in foo.c I use some standard C libraries like string.h and math.h . Where should I include them? Directly in the foo.c file, in the foo.h file or in both? Are #ifndef instructions necessary? If so, how do you use them correctly?
If you need these files in the .h
as well, you include them there (e. g. for types used in function prototypes). If you need them only in your .c
, include them there.
Q4. After writing the foo.c and foo.h file, am I all ready to go? Like, I don't need to compile them or anything, right? I can just #include them wherever I need just like that?
You can compile them in order to get something callable. If you don't compile your program, you cannot use it. Or do I understand you wrong?
Q5. Somewhere else I've read that if I want to use a custom library these are the steps that I need to follow:
[snip]
Indeed, this is one way to go. The steps 1, 2 and 4 cannot be omitted for obvious reasons. But you can execute step 3 and 5 together by doing
gcc my_proj.c foo.c
This compiles the given files and then links them together in one call.
Why do I only need to include foo.h in the file in which I want to use foo.c functions?
That's because the resulting object file contains information for the linker about which function it needs from other object files.
What exactly is an object file?
It is what results from compiling one source file. If you link several object files together, you get a running executable.
In other words: An object file is the compiled version of a source file. It "provides" the identifiers needed by other object files, and it "requires" other identifiers provided by other files. Linking them together means that the required and the provided objects are connected in an appropriate way so that the program can run.
Example: You have a foo.c which defines the functions foo
and test
. Then you have a main.c which makes use of these functions and provides a function main
. In the end, they are linked together and combined with the startup code which is needed to start a program and which calls main()
. The points in main()
where foo()
and test()
are called respectively are marked in a special way so that the linker can put the actual call address there.
Upvotes: 3