Emmanuel Delahaye wrote:
What's the best way to use extern when using multiplefiles that is
easiest to maintain?
First of all, try to avoid the use of global scope variables.
Read-only are acceptable, but read/write are source of trouble.
However, if you insist ...
Is it best to declare:
extern int a;
in a header file and include the header file in all files except
where it's defined.
Almost. The header should also be included in the definition source
file. This is the only way to check the match between the
declaration and the definition.
/* data.h */
/* usual guards ommited */
extern int x;
/* data.c */
#include "data.h"
long x; /* ERR! */
It also allows nice things like :
/* data.h */
/* usual guards ommited */
extern int a[128];
/* data.c */
#include "data.h"
int a[];
The size definition is now unique, public and centralized. It helps
reading and maintenance.
Thanks. I'm just trying to understand best practice use of the
keyword extern since I do not program for a living, but I would like
to start a project at source forge this year. And I am just double
checking the basics.
So the best practice would be to use global static variables in practice
Note that the word "global" does not exist in the C standard. The
term you are looking for here is "file scope" which is well defined by
the C standard.
All declarations and definitions written outside of any function in a
file have "file scope". Their scope lasts from the point of the
definition or declaration until the end of the translation unit being
compiled.
File scope definitions and declarations have external linkage by
default, unless the keyword static is added.
One never needs to use the extern keyword with a function definition,
prototype or declaration. All references to functions have external
linkage by default.
One needs to us the extern keyword for declarations (not definitions)
of data objects that are defined elsewhere. That is because of the
tentative definition feature in C.
If, outside of any block in a file, you have the three file scope
declarations:
extern int x;
int y = 0;
int z;
...then here is how a C compiler understands them.
-- extern int x; If there is no other file scope declaration of this
object in the source file, the compiler will treat it as a simple
external declaration. If any code in the source file access 'x', the
compiler will generate an external reference for it. In the final
stage of creating the executable program, usually called linking, the
int 'x' must be provided by another source file or library.
-- int y = 0; This is a definition of an int named 'y' that has
static storage duration, external linkage, and file scope. It will be
initialized with the value 0 before main() is called, and its lifetime
will be the entire execution time of the program. Even if none of the
code in the source file access 'y', the compiler will generate an
external definition for it. If there is more than one external
definition of this object in the final program, the result is
undefined.
--- int z; This is a 'tentative definition'. If there is no other
declaration for this object, then at the end of the file the compiler
will automatically create a definition "int z = 0'" and create the
object.
rather than modifiable extern variables? How should extern be used
then?
As to the use of variables with external linkage, modifiable or not, I
will say this: All absolute rules are rubbish, including this one.
Modifiable objects with wide scope, whether they have external linkage
or not, can be and often are abused and become the cause of hard to
find program defects. Nevertheless, like almost every other feature
of the language, they can be used properly and sometimes they are the
best solution to a problem. On the other hand, many times there are
better solutions possible.