26

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 the foo function without adding extern?

Updated the prototype.

gcc file1.c file2.c throws: warning: implicit declaration of function foo.

3
  • 2
    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 add int foo(); above main Commented Jan 4, 2012 at 14:48
  • @Seth: please always -include -Wall when giving gcc examples - it helps to get noobs into good habits. Commented Jan 4, 2012 at 14:54
  • I updated the question. I do it with -Wall. Commented Jan 4, 2012 at 14:55

4 Answers 4

54

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 
$ 
Sign up to request clarification or add additional context in comments.

6 Comments

The C99 pre-defined identifier is __func__. Prefer this to the gcc specific __FUNCTION__.
I 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.
Also please always include -Wall in any gcc command line example.
@PaulR What's the -Wall for?
@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.
|
8

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;
}

3 Comments

can I do it without any header files just by compiling the two together?
You still need a forward declaration of foo(), which you could do in file1.c if you want.
@mary yes, header files are for the compiler but this is done by the linker
7

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.

11 Comments

You don't need extern for calling a function, you only need the prototype, like int foo(); in the header and the body in file2.c
@Seth: true - you don't need it, but there is nothing wrong with making it explicit.
I'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 using extern on the prototype is completely baseless, unless you know something I don't (which is likely)
@Seth: not at all - the prototype is extern whether you explicitly declare it extern 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 explicit extern declaration form these days.
Note that until you are using C23, the line void foo(); // prototype for function foo() in file2.h provides a declaration of fucntion foo() but does NOT provide a prototype for the function. The empty parentheses say "takes an undefined list of arguments, but is not a variadic function (like printf() — there is no , ... at the end of the prototype)". Providing a declaration is sufficient to allow the function to be called in C99, C11, C18.
|
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.