I have designed a simple header called parser.h and whose code is:
#define MaxLinea 25
#define MaxFields 15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int parser(FILE * file);
I also have a main.c program which has the following code :
#include <stdio.h>
#include <string.h>
#include <parser.h>
#include <parser.c>
int main (int argc, char *argv[]){
FILE *file;
if(argc == 2){
file = fopen(argv[1],'r');
parser(file);
}
return 1;
}
I've tried to simplify the code as much as possible, so here's how I wanted to structure the files :
(1) The main.c program controls the main thread, making the appropriate calls.
(2) The program parser.h serves as the header for parser.c .
(3) The program parser.c supports main.c (because it has a helper function for main.c inside it ).
So main.c calls parser.h and parser.c , and parser.c calls parser.h .
However, running the build using the gcc -Wall -Wextra -o main main.c command throws the following (and only) build error :
main.c:3:10: fatal error: parser.h: No such file or directory #include <parser.h> ^~~~~~~~~~ compilation terminated.
I have all three files in the same path and I only intend to compile main.c . I have not compiled the rest because I understand that only the ".c" files are compiled, while the ".h" files are, so to speak, information for the executable modules (the ".c" ones) and, therefore, they are not they will be executed, that is, they do not need compilation. Compiling a ".h", however, doesn't change things either (tried that too and nothing). On the other hand, compiling parser.c I don't know if I should do it or not, but it doesn't matter to the compilation error that pops up, since it doesn't even deal with the compilation with parser.c .
How then do I include the ".h" files in main? Should I also compile parser.c with the same command as main.c or does it have special treatment? Thanks.
#include<>
vs#include""
If you use
<>
in theinclude
, the compiler will use absolute paths. These are ones that the compiler already has saved. In them you will find the standard library files such asstdio.h
. To these paths you can add using the flag-I
.In order for your program to compile, you would have to add the directory where you are working to the include path. You would have to add to the flags
-I.
(Remember it.
represents the current directory). You would do this if you added a library to your code, but for the current use case there is a better solution.If you use
""
in theinclude
, the compiler will use relative paths. This means that it will look for the files in the directory you are working in (and in case it doesn't find them, it will use the absolute paths).In this case, the best option would be to change:
By:
include a
.c
?Your program should work with the above change, but it's not a good solution.
What you have to include (which is what we put in the
.h
) are the declarations (thestruct
, function signatures, constants, etc...). But you never have to include the implementations (which is what we put in the.c
), as this can be problematic 1 .And then how do I include the implementations of the functions? Easy, you pass the file to the compiler:
And as a note. The more files you add to it, the more tedious it becomes to add them all to the compiler. And if you build them all, all the time, the build process starts to slow down. It would be a good time to start learning how to use tools like
make
.include
guardsThis is more of a note than a problem. You mention:
If you realize, here you would stop including
parser.h
2 times, when in reality you only need it 1 time. For such small files this is usually not a problem, but headers grow in size, and when there are enough of them (and they are needed for other headers) they add up to compile time. To fix that you can do a check at the beginning of the header.You have to be careful that what you define is not a common name, or something that may have already been defined. Personally, I like to follow the Google style guide for this .
1: With the exception of the functions marked with
static
orinline
, these can be included. As for why it can be problematic, you will understand better as you add more files, since sooner or later, you will end up defining the function in 2 places.