Reputation: 761
I am trying to understand extern
and linking. As a simple demonstration I have written two C files: a main file which uses a function and another file that defines the function:
/* main.c */
#include <stdio.h>
extern void print_nos(int, int);
int main(void) {
print_nos(10, 20);
return 0;
}
/* print_nos.c */
#include <stdio.h>
void print_nos(int lower, int higher) {
int i;
for (i = lower; i <= higher; i++)
printf("%d ", i);
printf("\n");
}
I have two questions pertaining to this:
I know that I can simply pass both files as arguments to gcc at once:
gcc -o main main.c print_nos.c
And this works fine, but I wanted to do the linking explicitly using ld
, so I did:
$ gcc -c main.c # produces main.o
$ gcc -c print_nos.c # produces print_nos.o
$ ld -o main main.o print_nos.o -lc
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401050
As you can see, I get the above warning and when I try to run the output file :
$ ./main
-bash: ./main: No such file or directory
I do not have much experience in assembly so I do not where to begin troubleshooting this - any help is appreciated.
Secondly, when I remove the extern
specifier, and try running gcc -o main.c print_nos.c
the program compiles just fine. Does a function need to be declared extern
at all? When I peeked into all the standard include files like stdlib, stdio, etc I saw that all the functions have an extern
declaration. Should I therefore use extern
in my case (in actual code resembling the one above)?
Upvotes: 1
Views: 695
Reputation: 6898
I wouldn't recommend using ld
directly unless you know what you're doing and have a good reason. If you want to compile modules separately (which is a good idea, so you can recompile only the ones whose source files have changed) you can use gcc
to do both the compiling and linking, like this:
gcc -c main.c # produces main.o
gcc -c print_nos.c # produces print_nos.o
gcc -o main main.o print_nos.o
As for the extern
specifier, you don't need it for functions. Function declarations are implicitly extern
by default.
Upvotes: 5