Compiling multiple C files in a program
Solution 1
You don't need an extern
, but file1.c must see a declaration that foo()
exists. Usually this declaration is in a header file.
To add a forward declaration without using a header file, simply modify file1.c to:
int foo(); // add this declaration
int main(){
foo();
return 0;
}
Solution 2
The correct way is as follows:
file1.c
#include <stdio.h>
#include "file2.h"
int main(void){
printf("%s:%s:%d \n", __FILE__, __FUNCTION__, __LINE__);
foo();
return 0;
}
file2.h
void foo(void);
file2.c
#include <stdio.h>
#include "file2.h"
void foo(void) {
printf("%s:%s:%d \n", __FILE__, __func__, __LINE__);
return;
}
output
$
$ gcc file1.c file2.c -o file -Wall
$
$ ./file
file1.c:main:6
file2.c:foo:6
$
Solution 3
You can, but you shouldn't.
Use a header file, file2.h:
// file2.h
void foo(); // prototype for function foo()
Then add:
#include "file2.h"
in file1.c
To compile:
$ gcc -Wall file1.c file2.c -o foo
As a general rule it's better (more robust) to use a header file to define the interface of each module rather than ad hoc prototypes within dependent modules. This is sometimes known as the SPOT (Single Point Of Truth) principle.
Solution 4
It's ugly, but using gcc, you could:
gcc -include file2.c file1.c
-include
is a flag to the preprocessor which will include the contents of file2.c at the very top of file1.c. Having said that, it's a poor choice, and breaks down for all but the simplest of programs.
Related videos on Youtube
mary
Updated on July 05, 2022Comments
-
mary almost 2 years
I have the following two files:
file1.c
int main(){ foo(); return 0; }
file2.c
void foo(){ }
Can I compile and link the two files together so the
file1.c
will recognize thefoo
function without addingextern
?Updated the prototype.
gcc file1.c file2.c throws: warning: implicit declaration of function foo.
-
Seth Carnegie over 12 years
gcc file1.c file2.c
, also I don't know C's exact rules for function calls when it's not seen a prototype but you might have to addint foo();
abovemain
-
Paul R over 12 years@Seth: please always -include
-Wall
when giving gcc examples - it helps to get noobs into good habits. -
mary over 12 yearsI updated the question. I do it with -Wall.
-
-
mary over 12 yearscan I do it without any header files just by compiling the two together?
-
chrisaycock over 12 yearsYou still need a forward declaration of
foo()
, which you could do in file1.c if you want. -
Seth Carnegie over 12 years@mary yes, header files are for the compiler but this is done by the linker
-
Seth Carnegie over 12 yearsYou don't need
extern
for calling a function, you only need the prototype, likeint foo();
in the header and the body infile2.c
-
Paul R over 12 years@Seth: true - you don't need it, but there is nothing wrong with making it explicit.
-
Seth Carnegie over 12 yearsI've never seen anyone make a function
extern
just because it's in another file. Saying you can but shouldn't write a function in another file without usingextern
on the prototype is completely baseless, unless you know something I don't (which is likely) -
Paul R over 12 years@Seth: not at all - the prototype is
extern
whether you explicitly declare itextern
or use C's implicit rules. I put it there to make it clear for noobs that it's a prototype, but mostly people don't use the explicitextern
declaration form these days. -
Seth Carnegie over 12 yearsThen why do you tell him that he shouldn't write a function that is to be used in other files without writing
extern
? The word "shouldn't" is too strong here -
Paul R over 12 years@Seth: if you want to encourage good software engineering practices then you need to promote separation of interface versus implementation for each module. I'll take the
extern
out of you prefer - it's only there for clarity but clearly it bothers you. -
Seth Carnegie over 12 yearsI had no problem with the
extern
, it's telling someone what they should do here. As I said, I've never seen this before, ever. Have you? I don't see where should is backed up by anything. Usually when you tell someone what they should do, you also present reasons why they should, and I can't see any reason at all for this, not even "because everyone else does it" -
Paul R over 12 years@Seth: I've added some clarification to justify the "should" - ad hoc prototypes really should be discouraged.
-
pmg over 12 yearsThe C99 pre-defined identifier is
__func__
. Prefer this to the gcc specific__FUNCTION__
. -
Timothy Jones over 12 yearsI don't think it's good practice to pass the header to the compiler like that - if it's needed, the preprocessor will bring it in.
-
Seth Carnegie over 12 yearsIs there some external source that also advocates using
extern
on all prototypes? (i.e. that also says you should always useextern
) -
Sangeeth Saravanaraj over 12 years@TimothyJones My apologies. That is a nice point. Thanks for keeping a check on the answer! .. I have corrected it now!
-
Paul R over 12 years@Seth: pretty much any decent introductory textbook on software engineering should cover this - I don't have a specific example at hand that I can cite though.
-
Paul R over 12 yearsAlso please always include
-Wall
in any gcc command line example. -
Minuet over 3 years@PaulR What's the -Wall for?
-
Paul R over 3 years@Minuet: it tells the compiler to enable all warnings - compiler warnings are really helpful and important, particularly for people who are still learning the language, but unfortunately they are not enabled by default, Always compile with warnings enabled and pay attention to any warnings that the compiler omits.