How are you intended to include files in a C project? - c

I have three files.
trees.h
// a bunch of typedefs and function prototypes
#include <trees.c>
trees.c
// a bunch of function bodies
main.c
#include <trees.h>
This isn't right, because every function in trees.c is giving me "undefined type" errors about the type defined in trees.h. I've tried every configuration I can think of - include trees.c from main and include trees.h from trees.c, include trees.c at the end of trees.h, include it at the beginning of trees.h... Every combination of includes I could think of, and each one gives a different set of errors. Sometimes it's multiple defines, sometimes it's undefined functions...
So how exactly does this work? What do I put in which files, and which files do I include and where?

Like this:
trees.h
// a bunch of typedefs and function declarations (prototypes)
trees.c
#include <trees.h>
// a bunch of function definitions (bodies)
main.c
#include <trees.h>
Explanation:
#include is basically the same as copying the entire included file to this file (where you put the #include).
So including trees.h in main.c allows that file to know about functions in trees.c.
Including trees.h in trees.c allows functions lower down in trees.c to be usable and this is also where defines, etc. used in trees.c is specified.
You also may not know about creating multiple objects and linking them, refer to Joachim Pileborg's answer.
The (very ugly) alternative is:
trees.h
// a bunch of typedefs and function declarations (prototypes)
trees.c
#include <trees.h>
// a bunch of function definitions (bodies)
main.c
#include <trees.c>
Then you just need to compile main. But for any project of a few .c files, this becomes impractical.

You compile each source file into object files, then link these object files together to form the final executable. If you use e.g. GCC and compile on the command line you can put both source files in the command line and GCC will handle it for you:
$ gcc main.c tree.c -o tree
The above command tells gcc to compile and link the files main.c and tree.c, and name the output executable tree. You can also compile the source file separately into object files, and then manually link them together:
$ gcc -c main.c -o main.o
$ gcc -c tree.c -o tree.o
$ gcc main.o tree.o -o tree
In the above commands, the -c option tells gcc to create an object file, and the -o option tells gcc what to name that object file. The last command takes these object files and create the final executable and names it (with the -o option) tree.
In the source files, you include the header(s) needed, not the other way around.

The reason it's not working is because you have to use 'extern' to define a variable or function that is declared in a different include file to the standard ones. You should also save all header files as *.h. So, assuming you had defined the struct 'tree' in tree.h:
#include <tree.h>
int main() {
extern tree; /* Get variable 'tree' declared in tree.h */
extern make_tree(void); /* Get function make_tree() declared in tree.h */
make_tree(); /* Call function */
return (0); /* End */
}

Begin with not including implementation (.c) files. Only include header (.h) files. Include them whenever you need the types or functions declared in them. To avoid multiple declarations, use include guards (whatever they are - just google it).

The way to go is including your header file trees.h in trees.c and then including trees.c within main.c
Have a look at this thread here

Related

How to divide C code in different files

I'm doing a code in C right now and the problem is that it's quite large. I've been doing some research about how to separate this code and the solution more attracting is to try and put some generic functions in a header file instead of putting them at the beginning of my .c code.
The problem comes when I read about this header files and I see that they are used to define MACROS. I started reading about it and what I see is strange definitions for me of variables (I mean strange because I normally don't define that kind of variables in a .c file).
Any thoughts on how to do this before I get my hands dirty?
As long as I understand your problem, you are trying to make an header file for your project, am I right? If this is the case, perhaps you are referring to #ifndef, #endif etc. etc. These are commands that will be executed by the preprocessor. You should give it a read. When you have finished your header save it in .h extension. Furthermore, when including your header, this has to be in the same folder of the .c file and you have to include it like that :
#include "myHeader.h"
In the header you just have to write down the prototype for your function. Then create a .c file myHeader.c and do the actual function. Remember to include you header in both of your .c files.
To compile it use the following :
gcc -c myFile.c -o myFile.o
gcc -c myHeader.c -o myHeader.o
Then you have to link the objects and you are done :
gcc myFile.o myHeader.o -o filename

C include error multiple definition error

I'm encountering a classic error but still don't get why it occurs...
Below is the simplified explanation
Apparently I have two C files main.c and support.c
in support.c i have one function void bla(int input);
in main.c i have several functions using bla from support.c, and i included
#include<support.c>
at the top of main.c
However I cannot compile the project because of the error multiple definition of bla, first defined here (eclipse points to the definition of bla in support.c)
I know that optimally I would have to create header file support.h and gives prototype extern void bla(int input) there, but for this I have to include the .c file.
Thanks in advance.
The preprocessor will copy the contents of support.c, and paste it to main.c to replace the line #include<support.c>. So there are two definition of the function bla, one in support.c, the other in main.c.
The solution is, don't include an source file. Put the declarations of functions that you want to export in a header file support.h, and include the header file in main.c:
#include "support.h"
You don't include source files into other source files. Instead you make a header file (with the extension .h) that contains declarations of functions, i.e. function prototypes. Then you build both source files separately, and link them together to form the final executable.
So a header file support.h like
#ifndef SUPPORT_H
#define SUPPORT_H
void blah(void);
#endif
(The preprocessor #ifdef/#define/#endif things are for include guards, to protect from multiple inclusion in the same source file.)
Then the support.c source file
#include "support.h"
void blah(void)
{
/* Some code here... */
}
And finally the main.c source file
#include "support.h"
int main(void)
{
blah();
return 0;
}
If you have an IDE (like Visual Studio) if you add these files to your project the IDE will make sure everything is built and linked properly. If you're compiling on the command line, compile each source file into an object file (usually using an option like -c (used for GCC and clang)) and then link the two object files together to create the executable.
Command line example with GCC:
$ gcc -Wall -c main.c -o main.o
$ gcc -Wall -c support.c -o support.o
$ gcc main.o support.o -o my_program
The above three commands will first compile the source files into object files, and then link them together.
What compiler are you using?
When compiling, make sure you do this:
gcc main.c support.c -o yourProgram

Building object files that depends on other object files

EDITS: Including link to my makefile
I have a main program that calls a bunch of functions defined in other source files. This is not a problem because I am using cc -c functionSource.c functionHeader.h and generating object files before compiling my main program with cc main.c func1.o func2.o .... -o test.o
I am having problems when one of my functions depends on another function.
For example:
My main program calls an shuffle function which is defined in it's own source file and the shuffle function calls a swap function which in turn is defined in it's own source file.
When i try to generate the shuffle.o file for my main program using cc -c shuffle.o I get an undefined reference to swap error.
When I try to cc shuffle.c swap.o i get an undefined reference to main error.
Here is my makefile
How do I go about fixing this?
Found the problem. I had a swap function declared inside insertionSort.h and shuffle.h but no implementations.
Have a look to the man page: '-c' makes the compiler generating object files only (not trying to link).
Do the following:
cc -c insertionSort.c # => gives insertionSort.o
cc -c -c functionSource.c # => gives functionSource.o
cc insertionSort.o functionSource.o ...and-so-on... main.c -o test
It's not necessary to specify header files - it doesn't help.
BTW: If you have mor than one implementation file, it is rather useful
(a) to learn make
(b) stick to the convention that object files and programs should be named like th sources.
E.g:
foo.c => foo.o
bar.c => bar
etc - you get the picture.
This has nothing to do with make. You need to get a book on introductory C programming, that will explain how to use the preprocessor, and you need to examine the documentation for your compiler so you understand what the different compiler flags do (such as when you want to use the -c flag and when you don't, and what the difference is).
It's wrong to include header files (.h files) on the compile line. Only source files (.c) should be included on the command line when building object (.o) files. You should be adding the headers you need into your .c files using the #include directive: #include "insertionSort.h". If you're missing a reference to a function, then #include the header file that declares that function: #include "swap.h".

How to link multiple implementation files in C

I have a number of .c files, i.e. the implementation files say
main.c
A.c
B.c
Where functions from any of the files can call any function from a different files. My question being, do I need a .h i.e. header file for each of A and B's implementation where each header file has the definition of ALL the functions in A or B.
Also, main.c will have both A.h and B.h #included in it?
If someone can finally make it clear, also, how do I later compile and run the multiple files in the terminal.
Thanks.
Header contents
The header A.h for A.c should only contain the information that is necessary for external code that uses the facilities defined in A.c. It should not declare static functions; it should not declare static variables; it should not declare internal types (types used only in A.c). It should ensure that a file can use just #include "A.h" and then make full use of the facilities published by A.c. It should be self-contained, idempotent (so you can include it twice without any compilation errors) and minimal. You can simply check that the header is self-contained by writing #include "A.h" as the first #include line in A.c; you can check that it is idempotent by including it twice (but that's better done as a separate test). If it doesn't compile, it is not self-contained. Similarly for B.h and B.c.
For more information on headers and standards, see 'Should I use #include in headers?', which references a NASA coding standard, and 'Linking against a static library', which includes a script chkhdr that I use for testing self-containment and idempotency.
Linking
Note that main.o depends on main.c, A.h and B.h, but main.c itself does not depend on the headers.
When it comes to compilation, you can use:
gcc -o program main.c A.c B.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o program main.o A.o B.o
You must provide an header file just if what is declared in a .c file is required in another .c file.
Generally speaking you can have a header file for every source file in which you export all the functions declared or extern symbols.
In practice you won't alway need to export every function or every variable, just the one that are required by another source file, and you will need to include it just in the required file (and in the source paired with the specific header file).
When trying to understand how it works just think about the fact that every source file is compiled on its own, so if it's going to use something that is not declared directly in its source file, then it must be declared through an header file. In this way the compiler can know that everything exists and it is correctly typed.
It would depend on the compiler, but assuming you are using gcc, you could use something like this:
gcc -Wall main.c A.c B.c -o myoutput
Look at http://www.network-theory.co.uk/docs/gccintro/gccintro_11.html (first google answer) for more details. You could compile it into multiple object files/ libraries:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o mybin main.o A.o B.o
You want to use
gcc -g *.c -lm
It saves typing and will allow you to link all your c files in your project.

Which way should I compile my C code?

I have three files, test.c, foo.c, foo.h.
In foo.c i
#include "foo.h"
In test.c i
#include "foo.c."
Then when I compile my code, I use gcc -o test test.c, and it compiles.
However, my professor told me, I should use
#include "foo.h"
inside my test.c rather than #include foo.c, and I should compile it this way
gcc -o test test.c foo.c
Is the second way more preferred? If it is, why? What's the difference between these two compilation?
In most cases you should never include source files (apart from cases where you would probably want to include a piece of code generated dynamically by a separate script). Source files are to be passed directly to the compiler. Only header files should be included.
Although the way that your professor suggests is correct, the following way has more educational value in this case:
gcc -c test.c
gcc -c foo.c
gcc -o test foo.o test.o
The first two lines compile each source file to an object file, and the third line doesn't really compile but only invokes the linker to produce an executable out of the 2 object files. The idea is to make a distinction between compiling and linking, which would be performed transparently in the way your professor suggests.
The major reasons not to #include .c files in other .c files are:
Avoid duplicate definition errors: suppose foo.c defines the function foo(). You have two other files that use foo(), so you #include "foo.c" in both of them. When you try to build your project, the compiler will translate foo.c multiple times, meaning it will see multiple attempts to define the foo function, which will cause it to issue a diagnostic and halt.
Minimize build times: even if you don't introduce duplicate definition errors, you wind up recompiling the same code needlessly. Suppose you #include "foo.c" in bar.c, and you discover you need to make a one-line change in bar.c. When you rebuild, you wind up re-translating the contents of foo.c unnecessarily.
C allows you to compile your source files separately of each other, and then link the resulting object files together to build your applications or libraries. Ideally, header files should only contain non-defining object declarations, function prototype declarations, type definitions, and macro definitions.
It is common practice to #include header files instead of source files, and compile source files individually. Separation of concerns makes it easier to work with in large projects. In your example, it may be trivial, but could be confusing when you have hundreds of files to work with.
Doing it the way your professor suggests means you can compile each source separately. So, if you had a large project where the sources were thousands of lines of code, and you changed something in test.c, you can just recompile test.c instead of having to recompile foo.c along with it.
Hope this makes some sense :)
If you want to compile several files in gcc, use:
gcc f1.c f2.c ... fn.c -o output_file
Short answer:
YES the second way is more preferred.
Long answer:
In this specific case you will get the same result.
To have a dipper understanding you need first to know that "#include" statement basically copy the file it's include and put its value instead of the "#include" statement.
Therefore "h" files are used for forward declaration which you have no problem several different file will include.
while "c" files have the implementations, in that case if both files will implement the same function you will have error in linking them.
Lets say you would have "test2.c" and you will also include foo.c and try to link it with the test.c you will have two implementations of foo.c. But if you only include foo.h in all 3 files (foo.c, test.c and test2.c) you can still link them cause foo.h shouldn't have any implementations.
It is not good practice to include .c files.
In your case
Include foo.h in both test.c and foo.c , but add this inside your header file
#ifndef foo.h
#define foo.h
..your header code here
#endif
Writing the header the above way , ensures that you can include it multiple times , just to be on the safe side.
Coming to how you must put your code in files>
In foo.h
You place all your global structures ,and variables along with function prototypes , that you will use.
In foo.c
Here you define your modular functions
In test.c
Here you generally have your main() , and you will call and test the functions defined in foo.c
You Generally put all the files in the same folder , and the compiler will find them and compile them individually , they will be connected later by the linker.
gcc f1.c f2.c ... fn.c -o output_file

Resources