Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > keyword extern

Reply
Thread Tools

keyword extern

 
 
tweak
Guest
Posts: n/a
 
      06-26-2004
What's the best way to use extern when using multiplefiles that is
easiest to maintain?

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.

Or is it better to write

extern int a;

in all the files except where it's originally defined?

I'm just curious what the best practice is since I code
as a hobby. And I'm still learning and making lotsa
mistakes.

Thanks,

Brian

P.S. Thanks to whomever recommended Advanced Unix Programming
Second Edition. It's cleared up a lot for me. And it's
making me question as to whether I should drop linux and
move to openBSD.
 
Reply With Quote
 
 
 
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      06-26-2004
In 'comp.lang.c', tweak <> 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.

> Or is it better to write
>
> extern int a;
>
> in all the files except where it's originally defined?


Certainly not.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Reply With Quote
 
 
 
 
Yashesh Bhatia
Guest
Posts: n/a
 
      06-26-2004
tweak <> wrote in message news:<0a3Dc.3$151.1@fed1read02>...
> What's the best way to use extern when using multiplefiles that is
> easiest to maintain?
>
> 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.
>
> Or is it better to write
>
> extern int a;
>
> in all the files except where it's originally defined?
>
> I'm just curious what the best practice is since I code
> as a hobby. And I'm still learning and making lotsa
> mistakes.
>
> Thanks,
>
> Brian
>
> P.S. Thanks to whomever recommended Advanced Unix Programming
> Second Edition. It's cleared up a lot for me. And it's
> making me question as to whether I should drop linux and
> move to openBSD.


Well, my preferred way would be to declare it in all the .c files that
need the extern variable rather than put the extern declaration in the
header file and include the header file in the c files. The reason
being.

- If the variable was used by all c files, it would be better to make
it a global variable in the .h file.

- Keeping the extern declaration in the .c file instead of the .h
file will make it easier for other .c files that dont need the extern
variable but need other declarations from the .h file to include it.
 
Reply With Quote
 
umbs.sairam@gmail.com
Guest
Posts: n/a
 
      06-26-2004
> What's the best way to use extern when using multiplefiles that is
> easiest to maintain?


> 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.


> Or is it better to write
>
> extern int a;
>
> in all the files except where it's originally defined?


One of the purposes of using extern in multiple files is restricting
the visibility of the variable only to the file that needs to "see"
it. In your question, in both the cases the variable "a" is visible in
all the files. In such a situation, there is no benefit in using the
keyword "extern. You might as well declare the variable as global.

sarma
 
Reply With Quote
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      06-26-2004
In 'comp.lang.c', (Yashesh Bhatia) wrote:

>> Or is it better to write
>>
>> extern int a;
>>
>> in all the files except where it's originally defined?
>>

> Well, my preferred way would be to declare it in all the .c files that
> need the extern variable rather than put the extern declaration in the
> header file and include the header file in the c files. The reason
> being.
>
> - If the variable was used by all c files, it would be better to make
> it a global variable in the .h file.


No. A header is certainely not the place for an object definition for an
obvious reason. If you include the header in more than one compile unit, you
will have more than one definition of the object with the same name. This is
the kind of situation a linker can't handle, except by an error message.

> - Keeping the extern declaration in the .c file instead of the .h
> file will make it easier for other .c files that dont need the extern
> variable but need other declarations from the .h file to include it.


The maintainers of such a code will doom you for ever. Please don't do that.
The OP's first proposal was nearly the good one. Please read my previous
answer to learn why.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Reply With Quote
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      06-26-2004
In 'comp.lang.c', wrote:

> One of the purposes of using extern in multiple files is restricting
> the visibility of the variable only to the file that needs to "see"
> it.


It certainely is a bad practice. What if the type changes (int to long, float
to double, etc.) ? Because the compiler has no way to check the consistency
of the code, if you miss a change the code becomes inconsitent. This practice
is obviously wrong.

If you are concerned with the visibility of the global variables, which
is a good thing, there are other options:

- don't use global at all. (Use ADT's)
- give the user no right to change the data (a const pointer to the data)

/* data.h */
extern int const *px;

/* data.c */
#include "data.h"
static int x;
int const *px = &x;

Of course, in real life, data are gathered in some structure and a single
'context' pointer is enough.

Note that this 'protection' is just an intention. There is no way to prevent
an sloopy programmer to write and compile a code that uses a typecast to
force the pointer to a read/write access to the data. But it will invoke an
undefined behaviour. The ADT solution is safer.

> In your question, in both the cases the variable "a" is visible in
> all the files. In such a situation, there is no benefit in using the
> keyword "extern. You might as well declare the variable as global.


Sorry, I failed to understand your point. 'extern' doesn't make global a
variable. It's the lack of 'static' that makes it.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Reply With Quote
 
umbs.sairam@gmail.com
Guest
Posts: n/a
 
      06-26-2004
> > In your question, in both the cases the variable "a" is visible in
> > all the files. In such a situation, there is no benefit in using the
> > keyword "extern. You might as well declare the variable as global.

>
> Sorry, I failed to understand your point. 'extern' doesn't make global a
> variable. It's the lack of 'static' that makes it.


I am sorry if I did not explain myself clearly. If we have the
following files
(pseudo-code)

head.h
/* common to all files */

head1.h
/* used in file1.c */

file1.c
include "head.h"
include "head1.h"
/* code of file1.c */
......

headN.h
/* used in fileN.c */

fileN.c
include "head.h"
include "headN.h"
/* code of fileN.c */

Now, declare a variable in head1.h as int i and define it in file1.c
as i = 10. My argument in the above post is, if "i" is declared
multiple times using extern in all the files file2.c ... fileN.c then
the significance of "extern"ing is lost. The programmer could have
acheived the same functionality by declaring the variable in head.h

sarma
 
Reply With Quote
 
tweak
Guest
Posts: n/a
 
      06-26-2004
Emmanuel Delahaye wrote:
> In 'comp.lang.c', tweak <> 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
rather than modifiable extern variables? How should extern be used then?

And structures are preferred when appropriate?

Thanks,

Brian
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      06-26-2004
On Sat, 26 Jun 2004 10:19:23 -0700, tweak <> wrote
in comp.lang.c:

> Emmanuel Delahaye wrote:
> > In 'comp.lang.c', tweak <> 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.

> And structures are preferred when appropriate?
>
> Thanks,
>
> Brian


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
Minti
Guest
Posts: n/a
 
      06-26-2004
Emmanuel Delahaye <> wrote in message news:<Xns951474F0A1393hsnoservernet@212.27.42.72>. ..
> In 'comp.lang.c', wrote:
>
> > One of the purposes of using extern in multiple files is restricting
> > the visibility of the variable only to the file that needs to "see"
> > it.

>
> It certainely is a bad practice. What if the type changes (int to long, float
> to double, etc.) ? Because the compiler has no way to check the consistency
> of the code, if you miss a change the code becomes inconsitent. This practice
> is obviously wrong.
>
> If you are concerned with the visibility of the global variables, which
> is a good thing, there are other options:
>
> - don't use global at all. (Use ADT's)


Could you elucidate this point?

--
Imanpreet Singh Arora
isingh AT acm DOT org
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference of extern short *x and extern short x[]? Andre C Programming 5 07-17-2012 07:38 PM
extern keyword Seeker C Programming 5 07-03-2006 11:49 AM
Use of 'extern' keyword siliconwafer C Programming 5 07-31-2005 03:39 AM
how to use the keyword extern in c? ooze C Programming 16 08-30-2004 04:39 PM
extern const char * vs. extern const char []http://tinyurl.com/47e3k Thomas Matthews C++ 5 08-02-2004 10:36 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57