in reply to Re: Help - I'm a C programmer
in thread Help - I'm a C programmer

Excellent reply. Although I'd like to say that:
You should always avoid globals at all costs; it's just bad programming in any language.
Is wrongheadedness like most blanket statements in programming ("never use a goto!" "always enter loops at the top and exit at the bottom!" etc..).

You should avoid globals<super>*</super> wherever possible, but not go through great pains and contortions to do so. Sometimes they're more appropriate than passing parameters to every function in a system to handle every possible need that may require them. For our C programmer, errno is an example where having a variable that has a "global" scope is much more appropriate than having every function which might do I/O receive it (or a pointer) as a parameter and pass it around during exception handling.

<super>*</super>I'm including file-scoped lexicals and package variables in this category and not the ${special_character} variables. Those, for the most part, are evil.

Replies are listed 'Best First'.
Re: Re: Re: Help - I'm a C programmer
by Masem (Monsignor) on Jun 17, 2001 at 21:08 UTC
    The thing about global variables is not the way they work; it's generally the problem with namespace collisions.

    There are times when you do need something similar to a global variable functionality; in languages where namespace collisions can be easily avoided, such as C++, Java, Perl, or the like, you should never define a global variable, instead creating one at an Object or Package scope. Unforunately, you can't do the same for C; the best you can do is create a special variable with a very descriptive name to act as a global, such that the chance for namespace collision is low. Even with something like errno, that ought to be stored away in some non-global area to prevent some third party code overwriting it unintentionally before you have a chance to use it.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      If you want to store away errno, you can.

      But if you want to do that then you probably wanted to use a variable other than errno.

      Remember that the purpose of errno ($! to Perl programmers) is to pass a very specific type of error information implicitly between code that otherwise knows little about each other. Having each library define its own little custom error reporting tool just results in turning error handling into such a mess that nobody will bother to do it.

      Now I agree with both telling beginning programmers the naive rule, and telling more experienced programmers the fact that it isn't always true. But for me the litmus test is simple. The question is, "Is this something that I want to have all of my code be aware of?" If I don't want to always be thinking of it, then it shouldn't be global. If I don't want to always be thinking of it within this package, then it shouldn't be a package global either.

      So as you see, I am not religious about saying, "NO GLOBALS". However I don't use very many of them...

      I use, for #define symbols that are horribly global, names based on UUID's (a.k.a. GUID's). That cannot match anyone else's generated UUID, and is quite unlikely to match a random string of hex digits that someone just pulled out of the air or generated with some other algorithm.

      —John

Re: Re: Re: Help - I'm a C programmer
by Brovnik (Hermit) on Jun 17, 2001 at 22:55 UTC
    I agree with clintp's comments about globals.

    For me, the amount of globals I use depends very much on the type of code I am writing. (See useful discussion on styles of code @ Why I like functional programming).

    For e.g. an object class, I would expect no globals to be used in the implementation.

    For e.g. an event loop (driven my user input), where you have large numbers of entry points into the code, you don't want to handle the passing of the state around everywhere, specially when the state gets large.

    The "globals" though should be carefully restricted to the smallest possible scope so that they don't pollute. It should be rare that the scope is "main", for any Packages in Perl.

    Taking the errno example, I took the view recently that it was better to hide the implementation of errors and provide an error() function that would provide the most recent error, rather than expose the implementation of errors within the package. Now I can change the implementation later without breaking existing user code.
    --
    Brovnik

      For e.g. an event loop (driven my user input), where you have large numbers of entry points into the code, you don't want to handle the passing of the state around everywhere, specially when the state gets large

      Was this an example of when to use globals? This is exactly when using globals will come back and bite you a couple weeks/months down the line. If you have a large and complex "state", wrap it up into a meaningful structure; Then you just have to pass around a reference to that structure, which makes passing around a large state very easy.