Extern variables and header files

S

Samuel Thomas

Hello Everybody,

I am confused about the concept of variables declared as extern. I
understand that when a variable is declared as extern the variable
becomes accessible in different files. How is this different from
declaring a variable in a header file and then including the header
file where the variable is required?

Thanks for all the help
Warm Regards
Sam.
 
M

Morris Dovey

Samuel said:
> I am confused about the concept of variables declared as
> extern. I understand that when a variable is declared as
> extern the variable becomes accessible in different files. How
> is this different from declaring a variable in a header file
> and then including the header file where the variable is
> required?

Samuel...

You can /declare/ a variable as 'extern' in any file you like;
but you can /define/ it only once.

About header files and global variables:

If you want to /declare/ a global variable in a header file,
that's ok but not strictly required.

If you were to /define/ a global variable in a header file; and
then include that header file in more than one file, you'd be
multiply-defining the variable. The compiler could happily
compile the separate files; but the linker would take serious
offense because it would have the same name associated with
multiple objects and it would be unable to resolve references to
it/them.

HTH
 
M

Mark Gordon

So how do you tell the compiler when you're declaring and when you're
defining? I thought that the extern keyword tells it that you're
declaring, and that the variable (probably) exists in another file.

Yes, the extern keyword is declaring the variable, however it *may* also
be defined in the same file. Not having the extern keyword (for
variables) means you are defining it.
Surely if you don't use the keyword, including the
definition/declaration in the header file will always result in a
definition, and thus linker errors?

Just asking, before you go off half-cocked like most people on this
NG.

Common practice is to do something like:

/* foo.h */
#ifndef FOO_H
#define FOO_H

extern int blar; /* Declaring blar as having external linkage */

#endif

/* foo.c */
#include "foo.h"

int blar; /* Defining blar, this line ONLY occurs once */

/* bar.c */
#include "foo.h"
/* No *definition of blar, just the declaration from the include file */


So you have the declaration of blar in scope then the definition of blar
is encountered, allowing the compiler to ensure that the types match.
You only have one definition of blar, which does NOT use the extern
keyword. You have as many declarations of blar (by including foo.h) as
you need.

Just to confuse matters, functions prototypes don't need the extern
keyword to act as external declarations. Other than that they work, and
are used, in a similar manner.
 
J

Joe Wright

John said:
So how do you tell the compiler when you're declaring and when you're
defining? I thought that the extern keyword tells it that you're declaring,
and that the variable (probably) exists in another file. Surely if you don't
use the keyword, including the definition/declaration in the header file
will always result in a definition, and thus linker errors?

Just asking, before you go off half-cocked like most people on this NG.

Ease up John. Don't define objects in headers. Headers are for
declarations. You obviously know that and so does Morris. Also, 'extern
int x;' is a declaration and fits nicely in a header. The header might
be included in all your .c files. The definition (at file scope) 'int
x;' may legally appear in only one of your .c files but now 'x = 42;' in
any of the other file refers to this x.
 
M

Morris Dovey

John said:
> So how do you tell the compiler when you're declaring and when
> you're defining? I thought that the extern keyword tells it
> that you're declaring, and that the variable (probably) exists
> in another file. Surely if you don't use the keyword,
> including the definition/declaration in the header file will
> always result in a definition, and thus linker errors?

These errors will only result from a definition in the header
file - although a declaration in the header file /could/ result
in an error condition if there is no corresponding definition
anywhere in the link package.
> Just asking, before you go off half-cocked like most people on
> this NG.

Well, I do that a lot. Most of the regulars on this NG actually
do much better than I. It's worth the effort not to let it bother
you very much; and there's considerable benefit to be gained from
tapping into their knowledge and experience.
 
S

Samuel Thomas

Hello Everybody,

Thanks for all the replies for my qns. After going through all the
follow-ups I came to this conclusion.

Situation
-----------

Suppose I have a very big source(called big.c) file with many
functions. I decide to split the big file logically and hence put
similar functions together. I now end up having 3 files of source
instead of my first big file. Lets call the files A.c,B.c and C.c. In
big.c, suppose I have a global variable 'int commonvar' for all the
functions to use. When I split my files, this would mean I still need
to have my variable 'commonvar' in A.c,B.c and C.c. How do I do that?

Solution
-----------

I /define/ my variable as /int commonvar/ in A.c. I make a header file
called globals.h and I /declare/ the variable as /extern int
commonvar/ in the header. I then include globals.h in my remaining
files B.c and C.c. This solves my problem and now I can use my global
variable in all my files :)

why does this work?
-----------------------

When I include a header file, all the contents of the header file
actually get 'pasted' at places where I declare the header file, when
I compile. This means I actually get the line "extern int commonvar"
in both B.c and C.c. I have /defined/ commonvar in A.c and now have
declarations in B.c and C.c.

This means I now have the variable available in all my files.


Friends, do tell me if my conclusions on header files and extern
variables are correct.

Thanks
Samuel.
 
K

Kevin Easton

Samuel Thomas said:
Hello Everybody,

Thanks for all the replies for my qns. After going through all the
follow-ups I came to this conclusion.

Situation
-----------

Suppose I have a very big source(called big.c) file with many
functions. I decide to split the big file logically and hence put
similar functions together. I now end up having 3 files of source
instead of my first big file. Lets call the files A.c,B.c and C.c. In
big.c, suppose I have a global variable 'int commonvar' for all the
functions to use. When I split my files, this would mean I still need
to have my variable 'commonvar' in A.c,B.c and C.c. How do I do that?

Solution
-----------

I /define/ my variable as /int commonvar/ in A.c. I make a header file
called globals.h and I /declare/ the variable as /extern int
commonvar/ in the header. I then include globals.h in my remaining
files B.c and C.c. This solves my problem and now I can use my global
variable in all my files :)

Not quite. Firstly, you also want to include the globals.h file in A.c
as well - that way, your compiler will see both the declaration and the
definition, and if they don't match (because you made a mistake), it'll
tell you about it.

Secondly, it's usual for the header file that declares the objects
defined in A.c to be called A.h.

- Kevin.
 
M

Morris Dovey

Samuel said:
Situation
-----------
Suppose I have a very big source(called big.c) file with many
functions. I decide to split the big file logically and hence
put similar functions together. I now end up having 3 files of
source instead of my first big file. Lets call the files
A.c,B.c and C.c. In big.c, suppose I have a global variable
'int commonvar' for all the functions to use. When I split my
files, this would mean I still need to have my variable
'commonvar' in A.c,B.c and C.c. How do I do that?

Solution
-----------
I /define/ my variable as /int commonvar/ in A.c. I make a
header file called globals.h and I /declare/ the variable as
/extern int commonvar/ in the header. I then include globals.h
in my remaining files B.c and C.c. This solves my problem and
now I can use my global variable in all my files :)

why does this work?
-----------------------
When I include a header file, all the contents of the header
file actually get 'pasted' at places where I declare the
header file, when I compile. This means I actually get the
line "extern int commonvar" in both B.c and C.c. I have
/defined/ commonvar in A.c and now have declarations in B.c
and C.c.

This means I now have the variable available in all my files.

Friends, do tell me if my conclusions on header files and
extern variables are correct.

Samuel...

Sounds good to me. I would suggest choosing a more informative
name than globals.h and including the header in A.c as well. That
will allow the compiler to help out with additional error
checking during future compilations (when all of today's crisp
details may have become a little hazy.)

Now that you seem to have mastered this important concept, let me
offer another (related) dealing with globals - one that I've
found helpful when I was stuck using them:

I declare all global data in a header file as you're doing; and
then I code a module consisting /only/ of global definitions (and
sometimes methods to access this data). If the package name is
xyz, I call this module xyz_data.c - and I don't waste any time
wondering where any particular global has been defined.

Congratulations - you've taken a significant step foreward.
 
S

Sameer Oak

Morris Dovey said:
Samuel Thomas wrote:

Samuel's approach is good.
i've an another, i'd say straight and a bit simpler approach to
convey.
at times, it's needed to decide what data-items are to be made global.
all data
that are used across the varid source code files are needed to be
handled with an outmost care since they are available across the
entire source.

what one can do is, (s)he can decide what data are to be declared as
extern in the header and what not. the less important data-items, but
still needed globally, can be defined in one of the .c files and used
with extern qualifier in the others. even in this case, in my
suggestion, one has to avoid the global extern declarations in the .c
files. thus declaring such data as extern in the
respective functions seems a very logical approach to me.

thank you.
..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top