This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: newbie gcc question...
- From: Andrea 'Fyre Wyzard' Bocci <fwyzard at inwind dot it>
- To: "Michael Kahle" <geopoliticus at onebox dot com>,gcc-help at gcc dot gnu dot org
- Date: Tue, 30 Apr 2002 03:47:26 +0200
- Subject: Re: newbie gcc question...
Hi Michael
When you include a file using the #include directive, you don't need to
include it again from the command line.
The you are getting are generated at link time, when gcc tries to determine
where all the (external) functions and variables you referenced in your
code are.
A very fast description of what's goin'on:
In C (and C++ and many other languages) you have to make a distinction
between the DECLARATION of and function (or a variable) and its DEFINITION.
The declaration of a function tells the compiler that, somewhere, there is
a function with that name, parameters and type. You need only specify the
types, the names of the arguments are optional.
The definition tells what the function actually does. You must put there
the names for the parameters, as you will be using them in the function.
Sometimes declaration and definition are referred to as, respectively,
interface and implementation, because the former tells how a function is
invoked (how your code will interface with it), and the latter actually
implements the function.
Example:
void bla_bla1(int);
is a declaration. It tells that there is a function called bla_bla1(),
taking an int as an argument and returning no value (void).
void bla_bla1(int x) {
printf ("Blah blah blah... %d\n", x);
}
is a definition. It implements bla_bla1() as a function that prints Blah
blah blah...* to the standard output.
To use a function in your code, it must have been previously declared. (the
definition itself counts as a declaration, too.)
That's why, for example, to use the library function printf(), you must
#include <stdio.h>, the header files that contains the declaration of printf().
When you make a program, all the functions you use must (also that being
declared) be defined in exactly 1 place, where all the declarations will be
"pointed at".
Compiling a program is actually made of 2 steps (even if a compiler can
mask this, doing all the work on a single invocation).
[actually, more that two, but you can look at it in this way as a starting
point]
During the 1st step, the compiler proper translates all the source files
(.c, for example) into the respective binary files (.o, or .obj).
During the 2ns step, the linker is invoked, and it merges all the .o files
and all the specified libraries into a single executable, taking care to
resolve all the external object; i.e. all the function that are declared
but not defined are "addressed" to the place where that function is
defined. This place can be a standard library, linked in automatically (for
functions like printf() or malloc()), an other library (for example, math
functions declared in <math.h> are defined in the libm library, linked in
with the "-lm" option), or in another (.o) file.
If you declare and use a function, but never define it (because you have
not written the implementation, or not included the .o file or the
library), you will get undefined references to those functions.
In you example, you declared bla_bla1(), bla_bla2(), bla_bla3(), etc... but
you did not define them.
A correct example would be in the form of:
/* bla_bla.h */
void bla_bla1(int);
int bla_bla2(int);
/* end of bla_bla.h */
/* bla_bla.c */
#include "bla_bla.h"
void bla_bla1 (int x) {
printf ("Blah blah blah... %d\n", x);
}
int bla_bla2 (int y) {
int z = y*y;
printf ("Blah blah blah... %d\n", z);
return z;
}
/* end of bla_bla.c */
/* main.c */
#include "bla_bla.h"
int main (int argc, char** argv) {
bla_bla1 (12);
bla_bla2 (5);
return 0;
}
/* end of bla_bla.c */
You can compile and link this all in one step with
gcc main.c bla_bla.c -o bla
which will build an executable name bla ("-o" is used to choose the name of
the output) , which should print
Blah blah blah... 12
Blah blah blah... 25
If, on the other hand, you want to compile it in two steps, you could do:
gcc main.c -o main.o -c
gcc bla_bla.c -o bla_bla.o -c
The "-c" option instruct the compiler to just compile the code, without
linking.
Then
gcc main.o bla_bla.o -o bla
will build the same executable as before :-)
I hope to have been clear enough. If you need more answers, feel free to
write me.