Re: Poll: global buffers (long)

From: Bil Simser (bsimser@home.com)
Date: 07/20/01


From: "George Greer" <greerga@CIRCLEMUD.ORG>
> Who thinks the global buffers (buf, buf1, buf2, arg) need to go?
> Who wants to keep them?
> and why?

First off, global anything in general programming 101 is a bad thing?
It's sloppy and lazy coding. Even back in the old C days before there
was a hint of C++ or OO design in C programming, the hard and fast rule
(as told by K&R) was to not use global anything. Encapsulate all
programming so you either declare it on the stack and it will be tossed
away after the function goes out of scope or pass the value in by value
or by reference (depending on what you need to do with it) and keep
everything neat and tight like a good boy scout.

The one thing that does bother me about the buffer system is the fact
that a) it's global and hence is a potential accident waiting to happen
(see below) and b) requires extra attention to checking for global
overruns and magic numbers and all that jazz.

Why is a global buffer system bad? Because it means that if I write to
buf (or buf2, or ...) then that information stays there even when in a
function that doesn't need it. Let's say I decide to write a new
command. I build the prototype and just call send_to_char(buf) to the
user. Whatever was in buf before is repeated to the user. Could be
something useful, but certainly not what was expected. There's also the
issue that you need to be aware that these buffers exist. That, IMO, is
usually a bad thing especially for new coders. When you see a function
that immediately calls *buf = '\0' you wonder, "buf?? what is that!".
Also, as someone pointed out, it's really, really bad practice to rely
on information to be passed around using global buffers like the locate
object issue. As well, what if you decide that you want to modify a
function by inserting a call to something that by nature writes
something to buf then does a send_to_char and returns. Now your prestine
function that was expecting buf to contain something important is now a
wash.

There's been a couple posts that say globals are efficient. No, they're
efficient in that they are easy to work with. You don't have to keep
typing char buf[BUFFER_SIZE] in your function to declare them. They just
are. That's not efficient by my standards. As for the issues of
differentiating between local or global buffers, local ones always take
precendence which might be another reason to axe them. If you declare a
variable called buf in your function, it overrides the global buf for
the life of your function. However, what if you call another function in
the middle of yours that uses buf or perhaps you pass your buf to
another function that also uses the global one. Ugh. It just continues
to get messy from there.

Speed? Memory overhead. True it's less cycles to reference a global
buffer than declaring and using a local one but in this day and age I
don't think you should use that crutch as a reason for lazy coding.
Additionally, think of the newbie coders who write their function and
accidently call send_to_char(buf2, ch) when they really meant to call
send_to_char(buf, ch). More posts to the mailing list asking why a
function isn't work. More chatter. More secret black magic information
for those that haven't looked at the header files to see what this
buf/buf2 thing is all about.

Marshal Clines C++ FAQ Lite has as section on global variables called
Just Say No! which says "In fact, you should avoid globals althogether
whenever you can". Grant you, it's C++ but the rules are relevant here
(you can view the entire FAQ here, good reference:
http://www.parashift.com/c++-faq-lite/). Personally I do hate purists
who code by the book. True, the rules were established long ago by some
very smart people, but times change and we really shouldn't conforming
to rules for conformity sake. The structured programming fundamentalism
however does say "avoid global variables" but they really don't go into
the details of why so I can't really state a concrete why here, just
give some pros and cons to it all. Perhaps a good change, instead of
eliminating the global variables, would be to create a global.h and
global.c which holds all of these. Then people could go here and see
what is being used instead of trying to guess. If anyone has the time
maybe try running lint against some of the code to see what it says?

One additional thought is the use of static variables. In the case where
the code does share something between functions perhaps it should make
more use of static variables and especially static function names where
the function is only used in that one module. Just makes the code
tighter and better to maintain.

In any case, most C design books, papers, courses, etc. that I've seen
usually preach to minimize and/or elminate the use of global variables.
Is is bad? I don't know but I generally avoid using them when designing
systems.

liB

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/06/01 PST