Question:
C : Why is "extern" needed for functions in case of multi-file source code,with one main() function?
Sheer
2012-07-27 10:52:07 UTC
Suppose we have a program whose source code is split into two ".c" files "major.c" and "minor.c"

//major.c

#include
#include "minor.c"

extern void display();

int main()
{
display();
return 0;
}

--------------------
//minor.c

void display()
{
printf("Hello Yahoo");
}


If I compile it from the command prompt using "gcc -o major.exe major.c minor.c" then it kinda appends minor.c to major.c(just as we want) and compiles it as one file into major.exe.Also,if I compile "major.c" from Codeblocks GUI, then again it compiles fine and generates major.exe.Now PLEASE see if you can clarify the following for me:

1)Do we need any function, whose definition is in another file (but part of same program) to be tagged "extern"? The above program works fine even if we don't use "extern" while declaring display() in "major.c".One contributor had told me that "extern" tells the compiler that the definition of the function is in another file.But why then it works without extern?And if commands like "gcc -o major.exe major.c minor.c" and "#include "minor.h" essentially joins together files that constitute the program, then why we need extern AT ALL(for functions as well as variables) as after all, we are essentially dealing with one large file and the "definition in another file" thing means little?

2)In the above code, it works fine if I compile "major.c".But when I compile minor.c, it throws some errors quite expectedly as the prinf() there has no prototype (as there is no stdio.h there).Had minor.c been a large file, there might be many more errors.Can you tell me how we deal with this scenario? I mean,USING THE GUI how do we compile the files of the program which don't have the main() function to check if they are correct and have no errors?Say my program had 5 files, how do I compile those which don't contain the main() function? In this case,will it be wrong for me to use "#include" again in "minor.c" as it's already in "major.c"?

3)Do we need to use "extern" (if at all it's necessary) and "#include "minor.c" in "major.c" even if we are using the "Project mode" option in Codeblocks Gcc GUI?Or in Project mode we can use multiple files for the program as if they are part of one large file without worrying about hash-including or using "extern", and it's the IDE's job to join them together?
Three answers:
2012-07-27 19:29:52 UTC
You can include any file, although it is generally bad practice to include C source files. The key is to know how the include preprocessor directive works. Basically, whenever the preprocessor comes along the include directive, it will replace it with the contents of the file quoted. This should be fairly simple:



main.c:

#include "display.h"



int main(void)

{

        display();

        return 0;

}





display.h:

#ifndef DISPLAY_H /* Prevent multiple inclusion */

#define DISPLAY_H



extern void display(void);



#endif





display.c:

#include

#include "display.h"



void display(void)

{

        printf("hello, world\n");

}



Now, there are numerous ways to compile this program. The easiest is to pass both translation units to GCC like so:



gcc -o display main.c display.c





To answer your question about extern, it's never necessary for functions. The following declarations are equivalent:



void display(void);

extern void display(void);



Which one of these you actually use depends on your preference, I personally prefer the latter, but it's good practice to choose one and stick with it instead of alternating between both. It is only with object declarations that ``extern'' is required, since both of the following do different things:



int a;

extern int a;



The former is a declaration and definition, whereas the latter is simply a declaration.
Laurence I
2012-07-27 18:02:20 UTC
see http://www.wikihow.com/Compile-a-C-Program-Using-the-GNU-Compiler-%28GCC%29



BY DEFAULT THE COMPILER makes up for laziness

ALL Functions are EXTERN by definition so the compiler

HAS already done it for you



================================================





you should never include a .c



you should only include .h files.





if you compile the ONE file with an include .c

and a separate file with the file that was included.

then you have TWO versions of the OBJECT code.



EXTERN is used to declare something at the GLOBAL level

that exists throughout the lifetime of the program.



The purpose of having separate files is two fold



firstly separating out units of code helps in lots of ways. It helps you to develop

the code separately(two different programmers for instance) NOT JUST YOU

it also means .H files can be used to make other coded units CONFORM to a set of rules



thus

a set of EQUATES and a set of EXTERNS may be defined in a .H making ALL UNITS

compile with the consistent(right) TYPES. This also reduces compile time.

as programs grow huge to more than 500 source files you need every bit of help you

can get with compile times for changes.



secondly eventually it will get so big it wont compile as one file.



===============================================



besides havnt you caught on yet?



if you want to use the MATH object whats the point of compiling dead code

thats unused code, unless you actually use it?



thats why the MATH unit is coded separately nad an INCLUDE of a .H

file is the way you INCLUDE its EXTERNally visible procedures.



and its the same for all the other separately coded units.



=========================================

you compile a .C you get a .OBJ

after a few compiles you get a few .OBJ



you LINK the .OBJ files to create a .EXE.



The LINKER JOINS up all the EXTERNS together with the code that CALLS

the EXTERNS or REFERENCES them.



The EXTERNS all get RECORDED into the LINKED MAP file, so that when you

want to DEBUG your PROGRAM(your EXE) then you know where your EXTERNS

are.



dont forget a VARIABLE can be EXTERN as well as a FUNCTION is an EXTERN.



this is anoher reason why you must not compile a .C twice as it may have GLOBAL

variables.



You only COMPILE .C files you do NOT separately compile .H files

they are compiled for each .C that includes them.



never ever Include .C files.
john m
2012-07-27 17:57:01 UTC
you need it to indicate the function is defined somewhere else and nt int the main file so that the compiler knows where to look for it



also why would you compile minor.c by itself? it has no main function you need a main function in all of your programs





if you just want to compile it to a .o object file use -c option in gcc


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...