global variables are bad?

F

fabio

Why? i' ve heard about this, the usage of global vars instead of
locals is discouraged, but why?
thx :)
 
M

Michael Mair

fabio said:
Why? i' ve heard about this, the usage of global vars instead of
locals is discouraged, but why?

There is no such thing as a global variable in C.
What you probably mean is a variable with static storage duration
and external linkage. Why make such a fuss about denomination? The
storage duration and the linkage determine different sides of
"global".

Linkage: External linkage (implies file scope and) means that the
identifier (the "variable name") must be the only one with exactly
this name and linkage throughout the whole programme. As soon as
there is a declaration of the variable in scope, it is "visible"
and accessible in the respective scope. This can be another
translation unit; what does this mean? You are using the variable
for an internal status record and now someone, maybe even you
yourself, thoughtlessly or seemingly cleverly overwrites this
status. This can easily upset the internal workings of your
programme after some changes.
You now can reduce the visibility and accessibility of the variable
by giving it internal linkage (the declaration remains on file level
but is preceded by "static") which means it is only accessible within
one translation unit -- as long as you do not give its address to
some part of the programme outside --, or by giving it block scope and
no linkage (the declaration is within a function and preceded by
"static") which means it is only accessible from its declaration to
the closing } -- as long as you do not give its address to
some part of the programme outside.

Storage duration: Static storage duration means that your variable
exists throughout the whole life-time of your programme. It is
initialized only once and holds its value between two writing
accesses. How can this be bad?
1) Whatever part of your programme directly knows the variable or
at least knows its address, can modify it.
2) If a function uses this variable to keep track of some sort of
internal status and expects only certain status transitions, then
calling the function from two different points in your programme
can upset the function's logic and lead to invalid results. This
can be especially an issue if the function is part of a library
and this library is accessed by more than one programme or if you
have a multithreaded programme -- this situation is not covered by
standard C, so I will not go into detail. Read up on "reentrancy"
to understand the issues involved.

In addition, if you have more than one place in your programme
where a variable is used or modified, even if you all planned it
out carefully and have none of the situations described above, you
can more easily make a mistake when designing the algorithm using
this variable than when you just pass it or its address around in
a strictly controlled manner.

Cheers
Michael
 
R

Richard G. Riley

"Michael"posted the following on 2006-03-11:
There is no such thing as a global variable in C.
http://www.google.com/search?q=global+variables+in+c

What you probably mean is a variable with static storage duration
and external linkage. Why make such a fuss about denomination? The
storage duration and the linkage determine different sides of
"global".

Assuming he means the commmonly understood meaning of global variable
here is another answer:

globals are nasty (generally) when used in certain functions which
would be better off having local variables since there is no
programmatic need to share that data with any code outside of that
subset or class of functions. Things you wish to share are passed back
by pointers or as values. Occasionally a global structure can be used to.

The bottom line is that making things available to code which
doesnt need them is bad : it is not structured and it is not
modularised.

You do not want someone linking to your "global" when YOU
require it to maintain its integrity between invocations of your code
and not be accessible to the whims of every tom, dick and harry who
have added modules to your system.

There are thousands of articles on this on the web.
 
R

Richard G. Riley

"Richard"posted the following on 2006-03-11:
Richard G. Riley said:


http://www.google.com/search?q=tooth+fairy (nearly four million hits).

Just cos it's on Google, doesn't mean it exists.

You dont say? But when we find x thousand courses which are quite
happy to see "global variable" talked about in C then does it seem
quite right to start pretending it doesnt apply anymore in ng? No. Did
you read the initial reply? Did you think that was constructive for a newbie?

Yoou dont know or agree with the common meaning of "global variable" in C?
 
R

Richard Heathfield

Richard G. Riley said:
"Richard"posted the following on 2006-03-11:


You dont say? But when we find x thousand courses which are quite
happy to see "global variable" talked about in C then does it seem
quite right to start pretending it doesnt apply anymore in ng?

The word "variable" isn't all that useful, and the term "global variable" is
less useful still.
No. Did
you read the initial reply?
Yes.

Did you think that was constructive for a newbie?

Yes. No point lyin' to 'em.
Yoou dont know or agree with the common meaning of "global variable" in
C?

The term has no universally recognised meaning in C.
 
M

Malcolm

Richard Heathfield said:
The term has no universally recognised meaning in C.
Neither does "linked list". Or "pure function". Doesn't mean that such a
think doesn't exist.
 
R

Richard G. Riley

Richard G. Riley said:


The word "variable" isn't all that useful, and the term "global variable" is
less useful still.


Yes.

I did not think that reply in anyway
clarified anything.
Yes. No point lyin' to 'em.

One has to be practical. Not too clever for ones own good sometimes.
The term has no universally recognised meaning in C.

Neither do lots of things : but the art is in recognising the meaning
from a newbie. Any half decent programmer worth his salt knows and
recognises what is meant by a global variable and in that context C
certainly does support them and the reasons for not using them are as
prevalent as in other languages : which is, fater all, what the OP was
asking. I dont know, maybe I'm getting too old for this : there was a
time when people wanted to help : not just get one upsmanship points
on who can read the standards the best.
 
M

Michael Mair

Richard said:
I did not think that reply in anyway
clarified anything.

You could have posted a direct reply.
You just could have expanded on mine and said that you consider
it too technical to be of any use to a newbie -- and be done.

For me, it was important to clarify that there are three
conceptual sides to it:
- Linkage
- Storage duration
- Ease or difficulty of seeing whether the implemented design
is the intended one, let alone correct

The former two are joined to the latter but may give toothaches
on their own. If I failed to carry this point over, then shame
on me. If you understood it but did not clarify it to suffice
your standards, shame on you.
In addition, it _is_ important to know what you are talking
about. The concepts mentioned should help the OP find his way
through it and also find out which side leads to which problem.
It may very well be that he decides to use a "global" variable
with internal linkage because this is exactly what he needs --
after having thought about why he does not want the uncertainties
involved in an object with external linkage and potential problems
when linking.

One has to be practical. Not too clever for ones own good sometimes.

This is true.
Nothing ever is simple, though, so I consider it fair to tell
people a little bit more.
A perfect reply certainly would be one of Chris Torek type (useful,
clear, concise, written nicely) but I certainly am not up to that
as I am neither a teacher nor a native speaker.

Neither do lots of things : but the art is in recognising the meaning
from a newbie. Any half decent programmer worth his salt knows and
recognises what is meant by a global variable and in that context C
certainly does support them and the reasons for not using them are as
prevalent as in other languages : which is, fater all, what the OP was
asking. I dont know, maybe I'm getting too old for this : there was a
time when people wanted to help : not just get one upsmanship points
on who can read the standards the best.

The latter was not my intention. I post here to help and to
learn. I certainly do not pride myself on my often spotty knowledge
of the standard. You will guaranteedly find a couple of times
within the last month where I made a mistake and was glad because
it was corrected.
If you are saying that my reply was insufficient: You were free
to improve it. Next time I will take what you said into account
when answering a similar question.
If you are saying that I did it intentionally to show off, then I
think you are just once more out to look for an unnecessary fight
to pick -- and you are plain wrong.


Cheers
Michael
 
C

Chris Torek

"Michael"posted the following on 2006-03-11:(I think this is a bit of an overstatement, but:)
"Richard"posted the following on 2006-03-11:

... You dont know or agree with the common meaning of
"global variable" in C?

I do not know about the other Richard; but the problem I have with
the phrase is that there seem to be at least two *different*
"common meanings" for that phrase in C (there may be more, but
I have only seen two "commonly expressed" ones).

One refers to static-duration external-linkage objects:

% grep varx *.[ch]
foo.h: extern int varx;
bar.c: varx++;
foo.c: int varx = 42;
[etc]

These have uncontrolled access and "singleton" behavior (to borrow
terminology usually used with C++ and similar inferior attempts :)
at OO languages).

Another refers merely to static-duragion objects, which may have
only internal linkage:

% grep didinit *.[ch]
bar.c: static int didinit;
bar.c: we use didinit to gripe rather than auto-init'ing in order to
bar.c: if (!didinit) gripe("missing call to init routine");
bar.c: if (!didinit) gripe("missing call to init routine");
bar.c: didinit = 1;
bar.c: if (!didinit) gripe("missing call to init routine");

(people generally do not call these "global" if they are block-scope,
but do often call them "global" if they are file-scope). Variables
like this tend to be less objectionable; they have much better
controlled access, at least.
 
R

Richard G. Riley

You could have posted a direct reply.
You just could have expanded on mine and said that you consider
it too technical to be of any use to a newbie -- and be done.

I didnt : I didnt doubt the contents one bit. But at the end of the
day we know what is meant. It is a practical understanding that
evolves from knowing languages and what new programmers are really asking.
For me, it was important to clarify that there are three
conceptual sides to it:
- Linkage
- Storage duration
- Ease or difficulty of seeing whether the implemented design
is the intended one, let alone correct

The former two are joined to the latter but may give toothaches
on their own. If I failed to carry this point over, then shame
on me. If you understood it but did not clarify it to suffice
your standards, shame on you.

He was asking more about the use of them : not the issues with the
underlying system - unless I got the wrong end of the stick in which
case I apologise-
In addition, it _is_ important to know what you are talking
about. The concepts mentioned should help the OP find his way
through it and also find out which side leads to which problem.

My own thought is that it was way too technical for someone asking
about global and local variables in programming.
It may very well be that he decides to use a "global" variable
with internal linkage because this is exactly what he needs --
after having thought about why he does not want the uncertainties
involved in an object with external linkage and potential problems
when linking.



This is true.
Nothing ever is simple, though, so I consider it fair to tell
people a little bit more.
A perfect reply certainly would be one of Chris Torek type (useful,
clear, concise, written nicely) but I certainly am not up to that
as I am neither a teacher nor a native speaker.



The latter was not my intention. I post here to help and to
learn. I certainly do not pride myself on my often spotty knowledge
of the standard. You will guaranteedly find a couple of times
within the last month where I made a mistake and was glad because
it was corrected.

I'm not disputing the accuracy of you post. That is not my intent.
If you are saying that my reply was insufficient: You were free
to improve it. Next time I will take what you said into account
when answering a similar question.
If you are saying that I did it intentionally to show off, then I
think you are just once more out to look for an unnecessary fight
to pick -- and you are plain wrong.

No : but sometimes one must step back and consider who we are replying
to. Your reply was very, very technical IMO. And also it is unfair to
suiggest that "global variables do not exist in C". I still maintain
they do for the purposes of describing structured programming in C.
 
M

Michael Mair

Richard said:
I didnt : I didnt doubt the contents one bit. But at the end of the
day we know what is meant. It is a practical understanding that
evolves from knowing languages and what new programmers are really asking.


He was asking more about the use of them : not the issues with the
underlying system - unless I got the wrong end of the stick in which
case I apologise-


My own thought is that it was way too technical for someone asking
about global and local variables in programming.

Yep. However, if I am answering in c.l.c, I try to give a C answer.
If the OP asked in comp.programming, I would not have dwelled on
the term "global variable" at first but would have tried to shed
light on the different aspects nonetheless.
Stating that there are no global variables in C certainly is
hyperbole. Which was my intention: This makes one reconsider the
terminology used in this context.

If a colleague asks me a question, I often ask back what kind of
answer he is expecting -- the <insert product name here> internal
answer, the <insert product name here> user's view answer, the
general view answer and which flavour: the mathematician's answer,
the computer scientist's answer, the programmer's answer, or the
engineer's answer.
Not all combinations yield different answers, of course, but some
do -- and treating them this way can help the colleague much more
than a "default view" answer.

I'm not disputing the accuracy of you post. That is not my intent.

This much I gathered -- I think you disputed the intent of my post.

No : but sometimes one must step back and consider who we are replying
to. Your reply was very, very technical IMO. And also it is unfair to
suiggest that "global variables do not exist in C". I still maintain
they do for the purposes of describing structured programming in C.

If I write a design or algorithm, I may go with the term
"global", too. When writing code, I do not know a "global"
specifier or qualifier but implement what is conceptually meant
by "global variable".
As the concept is mapped to "static storage duration" but is not
clearly mapped to "external linkage" as it could also mean
"internal linkage", the implementation decision is a C specific
one.
In this case, I intentionally wore the _C_ programmer's hat.


As we are pretty much in agreement about the correctness but not
about the form of my reply, I suggest we end the discussion here.


Cheers
Michael
 
R

Richard Heathfield

Malcolm said:
Neither does "linked list". Or "pure function". Doesn't mean that such a
think doesn't exist.

Sure - but when the term has no universally recognised meaning, it needs to
be defined (i.e. given a meaning) before it can be meaningfully used.
 
R

Richard Heathfield

Richard G. Riley said:
I dont know, maybe I'm getting too old for this : there was a
time when people wanted to help : not just get one upsmanship points
on who can read the standards the best.

I advocate sticking to the terminology of the Standard not because I want to
score one-upmanship points (I already have plenty of those and to spare),
but because, in my experience, people learn to write portable C more
effectively if they can understand that terminology and thus apply the
information in the Standard to their own programming. This is why I
constantly refer to objects rather than variables, implicit conversions
rather than "implicit casts", and so on.

If you don't think I'm here to help people, you can't have been around very
long. (In fact, an archive search reveals that you've been posting to
comp.lang.c by the name "Richard G. Riley" since 23rd February of this
year.) I suggest you stick around a bit before you start passing judgements
on people.
 
J

Jordan Abel

Richard G. Riley said:


The word "variable" isn't all that useful, and the term "global variable" is
less useful still.


Yes. No point lyin' to 'em.


The term has no universally recognised meaning in C.

Things that it's _not_ are universally recognized, though - about the
only things that can be a "global variable" are objects with static
duration and either external linkage or file scope.
 
J

Jordan Abel

(I think this is a bit of an overstatement, but:)
"Richard"posted the following on 2006-03-11:

... You dont know or agree with the common meaning of
"global variable" in C?

I do not know about the other Richard; but the problem I have with
the phrase is that there seem to be at least two *different*
"common meanings" for that phrase in C (there may be more, but
I have only seen two "commonly expressed" ones).

One refers to static-duration external-linkage objects:

% grep varx *.[ch]
foo.h: extern int varx;
bar.c: varx++;
foo.c: int varx = 42;
[etc]

These have uncontrolled access and "singleton" behavior (to borrow
terminology usually used with C++ and similar inferior attempts :)
at OO languages).

Another refers merely to static-duragion objects, which may have
only internal linkage:

% grep didinit *.[ch]
bar.c: static int didinit;
bar.c: we use didinit to gripe rather than auto-init'ing in order to
bar.c: if (!didinit) gripe("missing call to init routine");
bar.c: if (!didinit) gripe("missing call to init routine");
bar.c: didinit = 1;
bar.c: if (!didinit) gripe("missing call to init routine");

(people generally do not call these "global" if they are block-scope,
but do often call them "global" if they are file-scope). Variables
like this tend to be less objectionable; they have much better
controlled access, at least.

What about external-linkage variables with block scope? [One could argue
that an external-linkage variable has an existence in its own right,
independent of a mere declaration, but is it "global"?]
 
R

Richard G. Riley

Richard G. Riley said:


I advocate sticking to the terminology of the Standard not because I want to
score one-upmanship points (I already have plenty of those and to spare),
but because, in my experience, people learn to write portable C more
effectively if they can understand that terminology and thus apply the
information in the Standard to their own programming. This is why I
constantly refer to objects rather than variables, implicit conversions
rather than "implicit casts", and so on.

Posting has a nasty habit of insinuating an attitude not there. I did
not suggest you were not trying to help : I suggested, rather, that to
deny "global variables" in C to a beginner is counter productive and
liable to confuse. Let people walk before they can fly IMO.
 
C

Chris Torek

What about external-linkage variables with block scope? [One could argue
that an external-linkage variable has an existence in its own right,
independent of a mere declaration, but is it "global"?]

This is why I said "at least" two: it depends on how fine you want
to make your various distinctions. :)

To get an external-linkage block-scope variable in C, we have to
use the "extern" keyword:

void f(void) {
extern int somevar;
...
}

If f() actually uses "somevar", this code will only compile if some
other code supplies an appropriate "somevar" variable. Then we get
into the question of whether "somevar" in f() is *the* "global"(?)
variable, or if the definition in zorg.c -- if that is where it is
-- is the "real" global, and so on.

As an aside: note that limiting the scope of variables, whether
to files or blocks, allows us to have two different variables with
the same name. For instance:

void f(void) {
int x;
...
}
void g(void) {
double x;
...
}

Talking about "the" variable "x" is confusing since there are now
two variables both named "x". (Of course, I am used to this in
person, as "Chris" is a rather common name. As with "real names",
we generally like to add disambiguators. Sometimes people will
use full names or initials, but I have occasionally been numbered.%)
-----
% But never "Number 6"! I will not be pushed, filed, indexed, stamped...
-----

In C, "linkage" of identifiers allows us to decide whether or not
two identifiers with the same name refer to the same object.
Identifiers with "no linkage" *never* refer to the same object:

void h(void) {
int i; /* i has no linkage */
... /* use i */
if (somecond) h();
... /* use i some more */
}

When h() calls itself recursively, you get two active "i"s, and
in some cases you need to decide on some way to talk about both "i"s
at the same time, usually by adding a disambiguator like "the
outer i" or "the inner i".

In this case, when we have two "i"s due to h() calling itself, they
both have the same scope (block) and linkage (none), but they are
different objects. I think this is best viewed by saying that
scope and linkage apply to a variable's *name*, while storage-duration
-- which seems to be a key ingredient in deciding, informally,
whether to call a variable "global" -- is actually an attribute of
the underlying object.
 
R

Richard G. Riley

What about external-linkage variables with block scope? [One could argue
that an external-linkage variable has an existence in its own right,
independent of a mere declaration, but is it "global"?]

This is why I said "at least" two: it depends on how fine you want
to make your various distinctions. :)

To get an external-linkage block-scope variable in C, we have to
use the "extern" keyword:

void f(void) {
extern int somevar;
...
}

For the sake of simplicity and using "global global" for the OP I
would envisage a simple example where a module links to a system wide
"global"

e.g

globals.h:
===========
extern int myGlobal;

globals.c:
==========
int myGlobal = 255; // defined in globals.h as externally linkable

useglobals.c:
=============
#include "globals.h"
..
..
..
int func(){
doSomething(myGlobal+1);
}
..
..


Now, to me that is and always has been a "global", but can see where
it can be complicated because it is not global if the include is
included or the extern is specifically embedded in the code.
 

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

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top