Gene
Gene

Reputation:

How do you link .c and .h files of the same name?

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

Answers (7)

Rob Wells
Rob Wells

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:

  • the ".h" file is your interface to the library, i.e. what you have to compile against, and
  • the matching *.c file is the implementation of what you intend the function to do.

So, as an example:

  1. a file add_integers.h just declares the function, say addInts(), that takes two integers and returns an integer that is the sum of the two, and
  2. a file add_integers.c(pp) provides the implementation of the function addInts() that uses an algorithm that taking two integers, adds them together, and returns the results.

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

dwc
dwc

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

Joel
Joel

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

Stack Overflow is garbage
Stack Overflow is garbage

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

Alex Gartrell
Alex Gartrell

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

jackrabbit
jackrabbit

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

Mehrdad Afshari
Mehrdad Afshari

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

Related Questions