Reputation:
When reading library source code, I see that there are .c
and .h
files of the same name. In the main source, the .h
file is included but not the .c
file. When I look at the code in the .h
file it also doesn't #include
the .c
file of the same name. Am I missing something? Does the compiler automatically include a .c
file when a .h
file of the same name is #include
'd?
Upvotes: 6
Views: 6473
Reputation: 37133
There's a bit of a misnomer in your question. You compile against *.h files and, disregarding inlines, you link against *.c files.
If you go back to basics you can say that:
So, as an example:
The implementor of the addInts() function is free to make modifications to the software that implements the addInts() function.
Providing the interface to the addInts() function isn't modified at all (i.e. addInts.h isn't modified at all), then a new shared library containing the modified implementation of the addInts function is free to be distributed without people having to recompile against the new addInts library release.
Wow! Why does reading this explanation sound like Danny Kaye and "The Vessel with the Pessel"?
You might like to have a look at Bertrand Meyer's work with Eiffel and "Design by Contract".
Upvotes: 1
Reputation: 24910
Typical .h
files serve as a "table of contents" for the .c
file, including such things as function prototypes, typedefs and the like. Programs include the .h
so that they know about the functions and types.
The .c
files are compiled separately and produce object files (.o
or .obj
) that contain the actual code.
The object files are then tied to the main program through a Makefile, Project file, or similar method. Then the object files are linked with the main program, producing a functional whole.
In the case of libraries, there is no main program. The object files are gathered together and put in a special format (for static or dynamic libraries). Any program using the library would include the .h
as above, and link against the library.
Upvotes: 9
Reputation: 359
If I want to make a static library in C or C++ I will put my functions prototypes in the .h and the actual functions codes in the .c or .cpp. After that I compiled my .cpp to make a .lib
To link my .h to my .lib I write this preprocessor command in the .h
#pragma comment (lib, "theNameOfTheLibFile.lib")
After that if I include the .h in a program, my program knows where to find the matching library.
Upvotes: 0
Reputation: 248129
There is no magic. When a C program is compiled, there are two major steps to it.
First, each individual compilation unit is compiled in is isolation. (A compilation unit is basically one .c file, plus everything it includes).
At this stage, it doesn't know anything about what's contained in other .c files, which means that it can't generate a full program. What it can do is generate code with a few "fill in the blanks" spots. If, from foo.c you call a function that is declared in bar.h, and defined in bar.c, then the compiler can only see that the function exists. It is declared in bar.h, so we have to assume that the full definition exists somewher. But because that definition is inside another compilation unit, we can't yet see it. So the compiler generates code to call the function, with a little note on it saying "fill in the address of this function once it's actually known".
Once every compilation unit has been compiled in this way, you are left with a bunch of object files (typically .o if compiled by GCC, and .obj if you use MSVC), containing this kind of "fill in the blanks" code.
Now the linker takes all these object files, and tries to merge them together, which allows it to fill in the blanks. The function we generated a call for above can now be found, so we can insert its address into the call.
So nothing special happens if a .c file has the same name as a .h. That's just a convention to make it easier for humans to figure out what's inside each file.
The compiler doesn't care. It just takes each .c file, plus anything it includes, and compiles it to an object file. And then the linker merges all these object files together into a single executable.
Upvotes: 12
Reputation: 2554
The preprocessor doesn't do anything magical.
To include something within an included directory (hard to do with your own headers)
#include <foo.h>
or to include something within the same compilation directory
#include "foo.h"
All it does it take the text of foo.h and plug it directly in to the output. gcc a.c -E will print out what it looks like after preprocessing.
It's a 'dumb' process in that writing your own program that will handle #include
correctly is kind of a trivial exercise.
Upvotes: 1
Reputation: 5663
The .h file contains the declarations of the functions in the .c file. These declarations are needed by other .c files that want to use functionality of another .c file. So .c files are never included by .h files.
Each of the .c files is compiled into an object file and all those object files are then linked together into libraries or applications.
Upvotes: 4
Reputation: 422112
No. There's no need to include .c files in .h files. .h files are not normally passed as compiler input directly but their sole purpose is to be included by other files.
Usually, it's something like:
"a.c" includes "a.h"
"b.c" includes "c.h"
You compile "a.c" and "b.c" and link the output files.
Upvotes: 7