3

there is a function f in foo.c, I put f Prototypes into a header file.

and then, there are 3 question:

  1. does header file must named foo.h?
  2. does foo.c and foo.h must be in the same directory ?
  3. If the answer to both questions is no, that is to say, a header file can named f.h, foo.c and f.h can be in different directory. look a example:

~/cfile/foo.c

#include "~/hfile/f.h"
int f(void){
     ...
}

~/hfile/f.h

int f(void);

~/main/cmain.c

#include "~/hfile/f.h"
int main(void){
    f(); 
    ...  
}

Then, when I call f function in cmain.c, cmain.c can find f.h by #include directive, but how cmain.c find foo.c by f.h, because cmain.c only include f.h not include foo.c? or how the compiler or linker find foo.c by f.h?

Guo
  • 1,761
  • 2
  • 22
  • 45

7 Answers7

6

does header file must named foo.h?

No, but using names that tie relevant parts of the program together (even if it's a structural tie, and not a logical tie) is a very sound thing to do. Remember that code/source trees are for humans, not machines.

does foo.c and foo.h must be in the same directory

No. But the include paths must be setup properly so foo.c could be built.

but how the compiler or linker find foo.c and call f from foo.c?

You have to specify these things for the compiler/linker. Consult their documentation. Since doing it for large projects can be a bit daunting, there are even tools that manage builds for you, based on rules you specify. One classic example is the make program.


As for your added code samples. Simply including headers is not enough information to build a program. The header only includes declarations. You must direct you linker to take the relevant object files and link them into a single executable.

Think of if as jigsaw puzzle. Each declaration is dent in an object file, with a particular shape. Each function definition is bump in the object file with a particular shape. It's the linker's job to fit bump to dents like you would when putting the puzzle together.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
3

1. does header file must named foo.h?

That is not necessary however it can be convenient and most of the time an unwritten rule.

2. does foo.c and foo.h must be in the same directory ?

This is not necessary. You can give the c compiler include directories. Or you can include relative to a directory e.g.

#include "inc/foo.h"

3. If the answer to both questions is no, that is to say, a header file can named f.h, foo.c and f.h can be in different directory. Then, when I call f function, it can find f.h file by #include directive, but how the compiler or linker find foo.c and call f from foo.c?

See answer 2. For example see gcc manual with the -I option (https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html)

Update: Since the question was extended, maybe you can also look at an older post C/C++ header and implementation files: How do they work?.

Community
  • 1
  • 1
EmbedWise
  • 184
  • 1
  • 12
2
  1. no, you can name the header file whatever you like
  2. no, you can place the header file wherever you like
  3. if the header file isn't placed in the same location as the source file you have to hand over the location of the header file to the compiler. How to do this for gcc is described in the answer to this question: How to include header files in GCC search path?
eega
  • 479
  • 8
  • 20
2

You can name your files anything you want. You can put your files almost anywhere you like, as long as you correctly tell the compiler and linker where those files are. You don't even have to have the filenames end with .c and .h - those are mostly just conventions, but good ones. I really recommend that you go with .c and .h filename endings!

Say you call one file foo.c and put it in the ~/my-sources directory. Also say you call the other file bar.header and put it in the ~/my-headers directory. Then your #include directive would have to look something like this:

#include "../my-headers/bar.header"

This assuming that you are on a UNIX-like system. You would have to apply your knowledge of the operating system you are using to make the #include directive work properly.

Because the header file is included in the source file when compiling, it is actually almost exactly like having the entire contents if the header file inside the source file. So as long as you tell the compiler where to find your files (by the command line when compiling, and by having correct paths in your #include directives), you can put your files anywhere.

Anders Marzi Tornblad
  • 18,896
  • 9
  • 51
  • 66
2
  1. No
  2. No
  3. When you want to compile the output (can be a process or a static/dynamic library) you give the compiler the source files (in your case foo.c) and then it will search all these source files for the function's definition.
SHG
  • 2,516
  • 1
  • 14
  • 20
2
  1. does header file must named foo.h?

NO.

  1. does foo.c and foo.h must be in the same directory ?

NO.

  1. If the answer to both questions is no, that is to say, a header file can named f.h, foo.c and f.h can be in different directory. Then, when I call f function, it can find f.h file by #include directive, but how the compiler or linker find foo.c and call f from foo.c?

It's depend on you. If you put header f.h and source file foo.c in the same directory, then simply add a header file into foo.c file, like:

#include "f.h"

But, If you put header f.h and source file foo.c in the different directory, then add a path of header file into foo.c, like:

#include "Your_header_file_Path/f.h"
msc
  • 33,420
  • 29
  • 119
  • 214
1

#include literally inserts the referenced file where it's used.

View the preprocessor intermediate if you want to know what eventually is given to the compiler.

The linker works differently, it just has a list of all objects. If the object is there, it can find it.
If you didn't reference it properly, it will warn your with implicit declaration of some kind.

Jeroen3
  • 919
  • 5
  • 20