Duplicate error: C file include - c

One of my questions, as I'm pretty new to C is about ways to avoid getting the duplication error. Basically, when I build the project in Netbeans if I have the file in the project and also include it, I get that error.
Defining the functions static, is a correct way to avoid it? What other solutions are there? Thanks

.c/.cpp files shouldn't be included.
Move declarations to a common header file and include that.

As K. Horvath says, you shouldn't be including one c file in another. This means you have to provide an .h for each .c, compile the .c files into object files, then include the .h files as necessary and compile all the objects together with the .c containing main(). You can still end up with duplication in the .h declarations, however, which is where include guards come in.
#ifndef MY_HEADER
#define MY_HEADER
// all your type definitions, function prototypes, etc
#endif
WRT compiling each .c first, here's an example for gcc: you have a util.c file with various functions you want to use in main.c; util.c should then have a corresponding util.h you #include in main.c. Then:
gcc -Wall -g -c util.c
"-Wall" enable compiler warnings
"-g" include debugger symbols
"-c" will produce a .o (unlinked intermediate object) file instead of a normal executable.
Now:
gcc -Wall -g util.o main.c
This compiles main.c and includes the stuff from util.c which was compiled into util.o.
Since you're using netbeans, this may be theoretical -- generally IDE's do all that for you. However, understanding the fundamental process may make it easier to understand your IDE ;)

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

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

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

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

Including c files leads to undefined references

When I include c files, I start to get undefined references to other functions. Then, I have to start including the c files that contain the functions. How do I get around this? The undefined references are referenced in the c files that I include, but since I am not actually including those files, I get undefined references.
Generally one includes ".h" files, not ".c" files.
If you call a function declared in a .h file, it is not sufficient to compile the starting C file to get a complete program -- you also need to link in the object files associated with the code that implements the declared functions. These might be in a library, in which case you need to link with that library.
You need to either compile all the files at once (gcc *.c) or compile each .c file into a separate object file and then link them all into the executable:
gcc -c main.c -o main.o
gcc -c helper.c -o helper.o
gcc -c other.c -o other.o
gcc *.o -o main
And within each .c file you should only ever include .h files.
What do you mean by including? Including via the #include preprocessor directive, or including as in adding them to your project.
You cannot get around the fact that all of the functions that are called (or, generally, externals symbols that are referenced) in your program either have to be included in that program, or have to exist in a library that is linked to the program, explicitly or implicitly.
Just keep adding the source files that are needed until all the references are resolved.
If you can't do that, then you may have some problem with the program or build. Either the program is incomplete (missing source files), corrupt (missing parts of source files), or you have included an inappropriate source file into the build (e.g. a source file which is needed when the program is compiled for Unix, but you're building for Windows) or incorrectly configured (so it is conditionally compiling some code for the wrong platform) or the program is simply not ported to your system (makes references to library functions you don't have).

Including source files in C

So I get the point of headers vs source files. What I don't get is how the compiler knows to compile all the source files. Example:
example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H
int example(int argument); // prototype
#endif
example.c
#include "example.h"
int example(int argument)
{
return argument + 1; // implementation
}
main.c
#include "example.h"
main()
{
int whatever;
whatever = example(whatever); // usage in program
}
How does the compiler, compiling main.c, know the implementation of example() when nothing includes example.c?
Is this some kind of an IDE thing, where you add files to projects and stuff? Is there any way to do it "manually" as I prefer a plain text editor to quirky IDEs?
Compiling in C or C++ is actually split up into 2 separate phases.
compiling
linking
The compiler doesn't know about the implementation of example(). It just knows that there's something called example() that will be defined at some point. So it just generated code with placeholders for example()
The linker then comes along and resolves these placeholders.
To compile your code using gcc you'd do the following
gcc -c example.c -o example.o
gcc -c main.c -o main.o
gcc example.o main.o -o myProgram
The first 2 invocations of gcc are the compilation steps. The third invocation is the linker step.
Yes, you have to tell the compiler (usually through a makefile if you're not using an IDE) which source files to compile into object files, and the compiler compiles each one individually. Then you give the linker the list of object files to combine into the executable. If the linker is looking for a function or class definition and can't find it, you'll get a link error.
It doesn't ... you have to tell it to.
For example, whe using gcc, first you would compile the files:
gcc file1.c -c -ofile1.o
gcc file2.c -c -ofile2.o
Then the compiler compiles those files, assuming that symbols that you've defined (like your example function) exist somewhere and will be linked in later.
Then you link the object files together:
gcc file1.o file2.o -oexecutable
At this point of time, the linker looks at those assumtions and "clarifies" them ie. checks whether they're present. This is how it basically works...
As for your IDE question, Google "makefiles"
The compiler does not know the implementation of example() when compiling main.c - the compiler only knows the signature (how to call it) which was included from the header file. The compiler produces .o object files which are later linked by a linker to create the executable binary. The build process can be controlled by an IDE, or if you prefer a Makefile. Makefiles have a unique syntax which takes a bit of learning to understand but will make the build process much clearer. There are lots of good references on the web if you search for Makefile.
The compiler doesn't. But your build tool does. IDE or make tool. The manual way is hand-crafted Makefiles.

Resources