global variables are bad?

R

Richard G. Riley

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

typo fixed *
 
M

Malcolm

Chris Torek said:
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.
So one is a static global, the other a global global.
 
M

Mark McIntyre

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?

It merely means that the course teachers were ignorant. Thats not the
fault of anytone in CLC
you read the initial reply? Did you think that was constructive for a newbie?

Yes.
Mark McIntyre
 
N

Neil

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

Side effects. The bigger the program and the more the globals the
bigger the problem. Unintended and unwanted change to the globals can
happen. Then you get to figure out what it happened.
Variable (and function) scope should be limited. Use global only when
needed.
 
L

Laurijssen

Michael Mair said:
There is no such thing as a global variable in C.

Can somebody from clc come and change the g_ prefix into something more C
like from all our projects please? :) maybe el_ and ssd_ ?
 
R

Richard G. Riley

Can somebody from clc come and change the g_ prefix into something more C
like from all our projects please? :) maybe el_ and ssd_ ?

LOL. People need to understand that "global" is a concept : of course C
supports "global" variables. How global can be modified : but global
they are, and I'm yet to see a sensible argument to the contrary. The
fact that there might not be any "global" keyword doesnt alter
anything. Although looking at the asm output from Gcc is interesting :
hmm, whats, that? Aha : a .global data definition ....
 
M

Mark McIntyre

of course C supports "global" variables.

Define 'global'.

FYR, the word is used three times in the ISO standad, once with
reference to the preprocessor, and twice with reference to
side-effects of FP operations.
How global can be modified : but global
they are, and I'm yet to see a sensible argument to the contrary.

Then presumably you selectively skipped all the earlier arguments in
this thread.
Mark McIntyre
 
M

Michael Mair

Laurijssen said:
Can somebody from clc come and change the g_ prefix into something more C
like from all our projects please? :) maybe el_ and ssd_ ?

If you really have that many globals, please inform me
for which company you work so that I have a chance to avoid
your products.

Apart from that, if your coding guidelines prescribe a leading
g_ for all variables with external linkage and, say, sg_ for all
variables with internal linkage, then the mapping is injective and
well-defined. If you just threw external linkage and internal
linkage together or are not consistent in your naming scheme or
keeping to it, then there is not much hope -- neither for the
renaming nor for the conceptual cleanness of your programs.

If you really deem the replacement necessary, then use find and
grep to identify the files with
" word-boundary g _ alphanumeric word-boundary " and use your
shell's / DOS's for and sed for replacing. If you don't your way
around them, then there are still search and replace tools with
GUI to help you along.


Cheers
Michael
 
R

Richard G. Riley

If you really have that many globals, please inform me
for which company you work so that I have a chance to avoid
your products.

Why do you make so many assumptions of how many he has? Lots of
systems have a good few globals for efficiency and ease of use. Of
course limiting them is a benefit.
Apart from that, if your coding guidelines prescribe a leading
g_ for all variables with external linkage and, say, sg_ for all
variables with internal linkage, then the mapping is injective and

No more than defining all externs in a globals include. Having said
that, I like hungarian notation although its frowned upon in the Linux
world. Makes it too easy for people to read the code or something :)
well-defined. If you just threw external linkage and internal
linkage together or are not consistent in your naming scheme or
keeping to it, then there is not much hope -- neither for the
renaming nor for the conceptual cleanness of your programs.

If you really deem the replacement necessary, then use find and
grep to identify the files with
" word-boundary g _ alphanumeric word-boundary " and use your
shell's / DOS's for and sed for replacing. If you don't your way
around them, then there are still search and replace tools with
GUI to help you along.

I await the answer with interest.
 
M

Michael Mair

Richard said:
Why do you make so many assumptions of how many he has? Lots of
systems have a good few globals for efficiency and ease of use. Of
course limiting them is a benefit.

It sounds like it -- otherwise paying for me to come over and
fix it would certainly be a waste of time ;-)
Honestly, if you have one file with the "unavoidable globals"
and are careful using them then everything is alright; only if
your globals are happily distributed through the code is when
the overall integrity of the product can be doubted.

No more than defining all externs in a globals include. Having said
that, I like hungarian notation although its frowned upon in the Linux
world. Makes it too easy for people to read the code or something :)

Having seen identifiers which consist of five letters Hungarian
abomination and one or two letters "name" in order to keep the
6 letter limit, I cannot really claim that I am convinced.
Interestingly, even MS abandoned HN.
I await the answer with interest.

So do I :)


Cheers
Michael
 
R

Richard G. Riley

Having seen identifiers which consist of five letters Hungarian
abomination and one or two letters "name" in order to keep the
6 letter limit, I cannot really claim that I am convinced.
Interestingly, even MS abandoned HN.

When reading code from a printout I like it. In a code environemnt, no
need since the tools show the type.

But Hungarian was not what I meant to be honest : I was too hasty and
annoyed from the other thread.

Whyt would you call this in the academic world?


CStructMine *ptrDate = &myStruct;

int numRollsOfTheDie = getRolls();

Possibly "loose hungarian" or just "common sense good naming"? On
more than one project we introduced some basic naming standards and
the productivity soared : really. Far easier to see type and use even
just adding "ref" or "ptr" to a variable name : one of the biggest
causes of issues in C/C++ code reading and function calls
 
M

Michael Mair

Richard said:
When reading code from a printout I like it. In a code environemnt, no
need since the tools show the type.

But Hungarian was not what I meant to be honest : I was too hasty and
annoyed from the other thread.

Happens :)
Whyt would you call this in the academic world?

CStructMine *ptrDate = &myStruct;

int numRollsOfTheDie = getRolls();

Possibly "loose hungarian" or just "common sense good naming"?

I'd go for the latter. In the company I am working for at
the moment, the "naming conventions" go like that (parts of
that are C++, but there is only one set of conventions):
Start with 'p' for pointers and 'r' for references, accumulate
'p's and 'r's appropriately, with 'm_' for members and 's_' for
static members, do not use gratuitous '_' (essentially: Keep it
to the macros), use camel casing for member functions and
Pascal casing for other functions. Make the names telling.
In the case of libraries from different products, one also
gets some name prefixes, too, but these are not annoying.
There is some more stuff for enums, typedefs and classes but
that's about it. Personally, I'd even use less regulation
in some parts but this is about okay. When talking to the
oldstyle Windows programming disciples, I am very glad about
this set of rules in comparison.
On
more than one project we introduced some basic naming standards and
the productivity soared : really. Far easier to see type and use even
just adding "ref" or "ptr" to a variable name : one of the biggest
causes of issues in C/C++ code reading and function calls

Yep. Whatever helps and does not hinder.
The larger the group the more necessary to introduce this early.

Cheers
Michael
 
R

Richard G. Riley

Happens :)


I'd go for the latter. In the company I am working for at
the moment, the "naming conventions" go like that (parts of
that are C++, but there is only one set of conventions):
Start with 'p' for pointers and 'r' for references, accumulate
'p's and 'r's appropriately, with 'm_' for members and 's_' for

I hate m_ for members. There is "this" and the anchor object to
indicate that they are members. Es ist genug.
static members, do not use gratuitous '_' (essentially: Keep it
to the macros), use camel casing for member functions and
Pascal casing for other functions. Make the names telling.

"telling" can be difficult across languages (world), but at the end of
the day I've worked on many projects around the world and the code
language was in all cases, bar one, in English. Made for some pretty
freaky comments : we'd have been better off without them IMO:)
In the case of libraries from different products, one also
gets some name prefixes, too, but these are not annoying.
There is some more stuff for enums, typedefs and classes but
that's about it. Personally, I'd even use less regulation
in some parts but this is about okay. When talking to the
oldstyle Windows programming disciples, I am very glad about
this set of rules in comparison.


Yep. Whatever helps and does not hinder.
The larger the group the more necessary to introduce this early.

I had a huge argument about this. Some of the programmers wanted to
"express their freedom". After attempting to come to a "consensus" we
realised it was just getting silly : we instigated the rules against
the wishes of some of the older (more stuck in the wood) hands and the
proceeded to see nothing but better results. The code was regularly
reviewed, multistatement per line code removed, and guess what? The
programmers could move between modules with *ease* : in days before
people dreaded using "X"'s code because he used crap variable names,
insisted on breaking things down to a painfule level and basically not
use the strengths of the language. A few code reviews, standard
variable naming and standard ways of laying out loops and the issue
was gone. Underestimate something even as simple as the way you use
opening and closing braces : me, I'm a K&R man in that respect.
Cheers
Michael

cheers,
 
J

John Bode

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

File scope variables (globals) cause maintenance headaches mainly by
promoting tight coupling between what should otherwise be independent
functions or modules. If you're updating a function or module that
modifies a global, you have to make sure that change doesn't have
unintended side effects elsewhere. You have to make sure that the same
variable isn't being used in multiple, potentially conflicting contexts
(say as a sum in one function and an array index in another).
Otherwise you increase the risk of introducing bugs in other parts of
the program. It also makes it harder to make changes to the code as
the requirements change (which they do, a lot).

There are times when you need to preserve information between function
calls and have that information available to multiple functions;
however, those functions and globals should be grouped together and
placed in a file of their own, and the globals should not have external
linkage (i.e., they should be declared static at file scope). You
should *never* need to have a single variable visible across the entire
scope of a program (if you do, you may need to rethink your design).
 
J

John Devereux

John Bode said:
There are times when you need to preserve information between function
calls and have that information available to multiple functions;
however, those functions and globals should be grouped together and
placed in a file of their own, and the globals should not have external
linkage (i.e., they should be declared static at file scope). You
should *never* need to have a single variable visible across the entire
scope of a program (if you do, you may need to rethink your design).


This means putting the declaration in the header file, doesn't it?

I have always heard that was a bad idea. Or do you think it is just
less bad than the alternative of having a "variable with external
linkage" declared in the implementation (*.c) file, and defined in a
header file?

i.e. you could have just

module.h:

static int shared_int;


Or

module.h:

extern int shared_int;

module.c:

int shared_int;
 
J

John Bode

John said:
This means putting the declaration in the header file, doesn't it?

I have always heard that was a bad idea.

It's a bad idea to have a variable *definition* in a header file.
Or do you think it is just
less bad than the alternative of having a "variable with external
linkage" declared in the implementation (*.c) file, and defined in a
header file?

i.e. you could have just

module.h:

static int shared_int;


Or

module.h:

extern int shared_int;

module.c:

int shared_int;

If your intention is to have multiple modules access the same memory,
the second way is the correct way to do it (there are circumstances
where this is necessary, but not in the normal course of events). The
first way will cause each file that includes module.h to create its own
private instance of shared_int, so it won't really be shared.
 
J

John Devereux

John Bode said:
It's a bad idea to have a variable *definition* in a header file.

I always get this terminology mixed up for some reason (definition vs
declaration). I know what I meant!
If your intention is to have multiple modules access the same memory,
the second way is the correct way to do it (there are circumstances
where this is necessary, but not in the normal course of events). The
first way will cause each file that includes module.h to create its own
private instance of shared_int, so it won't really be shared.

Re the first way: Of course it won't work, I don't know what I was
thinking there! I never do that, so have never thought through the
consequences. I thought that is what you were proposing, but I now see
you just mean isolate all uses of the "global" variable into a single
module, then you can make it static and get rid of the external
linkage.

Re "variables with external linkage", I *have* had applications
degenerate into using them, even when starting out with good
intentions. For example, I have embedded systems that use shared
structures for e.g. "settings".

set.h:

struct
{
test_time;
temperature;
/*...(lots more items)...*/
} set;


A "user interface" module then allows the user to change the settings,
while the rest of the program is controlled by the setting values,
e.g. set.temperature. Everything has to include set.h.

I have not found a better way to do it, but don't really like the
result. I can make the structure definition static, then pass around
pointers to it everywhere, but that does not really change anything;
everything is still interdependent.
 
C

cappeca

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

Which is not very helpful for newbies, now you know.
If you don't think I'm here to help people, you can't have been around very
long. I suggest you stick around a bit before you start passing judgements
on people.

WTF? You're passing judgement on people based on post count?
 
C

Chris Dollin

cappeca said:
Which is not very helpful for newbies, now you know.

Why do you think that it isn't helpful to newbies to learn the Standard
terminology?
WTF? You're passing judgement on people based on post count?

Didn't look like it to me. Not /only/ on post count, anyways.
 
J

John Bode

John said:
I always get this terminology mixed up for some reason (definition vs
declaration). I know what I meant!

Yeah, I just wanted to amplify the point, as it's bitten me in the ass
on occasion.
Re the first way: Of course it won't work, I don't know what I was
thinking there! I never do that, so have never thought through the
consequences.

Welcome to my world. God knows how many times I've written something
here that, on reflection, wasn't what I meant to write at all.
I thought that is what you were proposing, but I now see
you just mean isolate all uses of the "global" variable into a single
module, then you can make it static and get rid of the external
linkage.

Re "variables with external linkage", I *have* had applications
degenerate into using them, even when starting out with good
intentions. For example, I have embedded systems that use shared
structures for e.g. "settings".

set.h:

struct
{
test_time;
temperature;
/*...(lots more items)...*/
} set;


A "user interface" module then allows the user to change the settings,
while the rest of the program is controlled by the setting values,
e.g. set.temperature. Everything has to include set.h.

I have not found a better way to do it, but don't really like the
result. I can make the structure definition static, then pass around
pointers to it everywhere, but that does not really change anything;
everything is still interdependent.

Yeah, I can imagine that embedded programming is one area where this
sort of thing crops up a lot (I don't do embedded programming, so I'm
just guessing). I should probably never say "never"; there *are* times
when global access is the right answer, it's just that it isn't common
outside of certain domains. For general-purpose applications
programming, it should be pretty damned rare.
 

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
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top