This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]