Stoneforever said:
Hi, I got a problem, I have three files, for example:
/****a.h*******/
#define X1 10
#define X2 10
.....................
/****b.c*******/
#include "a.h"
int add(int x,int y)
{
return x+y;
}
/****c.c*******/
#include "a.h"
void main()
{
int x,y;
x = y = 10;
add(x,y);
}
why the compiler give me the error: undefined reference to 'add', the
compiler i used is Dev-C++.
thanks, any help will be appreciated.
It depends on how you are trying to compile. I don't
know anything about Dev-C++, but here are 3 attempts
to compile with gcc, the first fails, the second works but
is not generally the desirable approach, and the
third is...less incorrect. (I would prefer that the add
function be compiled into a seperate .a or .so rather
that just building an object file, but for something
this simple, that's overkill.)
$ cat a.h b.c c.c
/****a.h*******/
#define X1 10
#define X2 10
extern int add(int x,int y);
/****** b.c *****/
#include "a.h"
int add(int x,int y)
{
return x+y;
}
/****c.c*******/
#include <stdlib.h>
#include "a.h"
int main(void)
{
int x,y;
x = y = 10;
add(x,y);
return EXIT_SUCCESS;
}
$ gcc -Wall -pedantic c.c
ld: Undefined symbols:
_add
$ gcc -Wall -pedantic c.c b.c
$ gcc -c -Wall -pedantic -c b.c
$ gcc -c -Wall -pedantic -c c.c
$ gcc c.o b.o
To clarify further: the first attempt to build
an executable from c.c fails because the
linker cannot locate the code for the add
function. Notice that it does compile correctly,
but it fails to link. Building the executable
consists of several steps, of which compilation
is only one. Often, the word "compile" has
been incorrectly conflated with the attempt
to build an executable, and it is an unfortunate
twist of language. I generally would agree
that c.c "didn't compile", but in fact, it did
compile--but you didn't build an executable
because the link step failed.
The second attempt to build works because
I explicitly tell the compiler (really the compiler
tool chain!) that it should take code from both
b.c and c.c and build an executable.
The third attempt (the final three commands)
first builds an object file from b.c into a file
named b.o. It does't link, because I specified
-c on the command line (I have no idea
how to do that with your compiler). In other words,
the command "gcc -c b.c" doesn't attempt to build
an executable. It just builds object code. The next
command compiles the code in c.c and builds
c.o. The final command takes the code from b.o
and c.o and builds an executable from them, ensuring
that there is exactly one function named "main" and
making sure that all the functions referenced from
main are present.
Hope that didn't confuse you further....